[Python-ideas] Proposal: Query language extension to Python (PythonQL)
Brice PARENT
contact at brice.xyz
Mon Mar 27 05:54:58 EDT 2017
Le 27/03/17 à 10:55, Pavel Velikhov a écrit :
> Hi Brice,
>
>> On 27 Mar 2017, at 10:17, Brice PARENT <contact at brice.xyz
>> <mailto:contact at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170327/f047019d/attachment.html>
More information about the Python-ideas
mailing list