Le 27/03/17 à 10:55, Pavel Velikhov a écrit :
Hi Brice,

On 27 Mar 2017, at 10:17, Brice PARENT <cont...@brice.xyz <mailto:cont...@brice.xyz>> wrote:

I prefer this a lot to the original syntax, and I really think this has much better chances to be integrated (if such an integration had to be done, and not kept as a separate module).

Also, maybe managing this with classes instead of syntax could also be done easily (without any change to Python), like this:

from pyql import PQL, Select, For, Where, GroupBy, Let

result = PQL(
    Select("x", "sum_y"),
    For("x", range(1,8)),
    For("y",range(1,7)),
Where(lambda x, y: x %2==0andy %2!=0andx >y, "x", "y"), # function, *[arguments to pass to the function]
    Where("sum_y", lambda sum_y: sum_y %2!=0)
    GroupBy("x"),
    Let("sum_y", lambda y: sum(y), "y")
)



So here’s the deal: small queries will look pretty decent in pretty much all paradigms, ORM, or PythonQL or your proposal. Once they get bigger and combine multiple pain points (say outerjoins, grouping and nested data) - then unless you have a
really clear and minimal language, folks will get confused and lost.

We’ve gone through a few query languages that failed, including XQuery and others, and the main reason was the need to learn a whole new language and a bunch of libraries, nobody wanted to do it. So the main selling point behind PythonQL is: its Python
that folks hopefully know already, with just a few extensions.
I get it, but it's more a matter of perception. To me, the version I described is just Python, while yours is Python + specific syntax. As this syntax is only used in PyQL sub-language, it's not really Python any more... Also, what I like with what I used, is that it is object-based, which allows any part of the query to be reusable or built dynamically. We might also extend such a PQL object's constructor to embed automatically whatever default parameters or database connection we want, or shared behaviours, like:

class MyPQL(PQL):
    def get_limit(self):
        if self.limit is not None:
            return self.limit

        return 10

    def __init__(self, *args):
        args.append(Let("sum_y", lambda y: sum(y), "y"))
args.append(GroupBy("x"))
        super().__init__(*args)

result = MyPQL(
    Select("x", "sum_y"),
    For("x", range(1,8)),
    For("y",range(1,7)),
    Where(lambda x, y: x %2==0andy %2!=0andx >y, "x", "y"),
    Where("sum_y", lambda sum_y: sum_y %2!=0)
)

Big queries, this way, may be split into smaller parts. And it allows you to do the following in a single query, instead of having to write one big for each condition

where_from = [For("x", range(1,8)),For("y",range(1,7))]
where = [Where(lambda x, y: x %2==0andy %2!=0andx >y, "x", "y")]
if filter_sum_y:
where.append(Where("sum_y", lambda sum_y: sum_y %2!=0))

if group_by is not None:
    grouping = GroupBy("x")

result = MyPQL(Select("x", "sum_y"), *where_from, *where, *grouping)

Side note : I'm not a big database user, I mostly use ORMs (Django's and PonyORM depending on the projects) to access PgSQL and SQLite (for unit testing), so I might not even have use cases for what you're trying to solve. I just give my point of view here to explain what I think could be more easily integrated and (re)used. And as I'm a big fan of the DRY mentality, I'm not a fan of the syntax-chaining things (as well as I don't really like big nested comprehensions).

-Brice
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to