<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p><br>
    </p>
    <br>
    <div class="moz-cite-prefix">Le 27/03/17 à 10:55, Pavel Velikhov a
      écrit :<br>
    </div>
    <blockquote
      cite="mid:8716ACD7-C609-4F9D-B9AF-9DBDA8369381@gmail.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      Hi Brice,
      <div class=""><br class="">
        <div>
          <blockquote type="cite" class="">
            <div class="">On 27 Mar 2017, at 10:17, Brice PARENT <<a
                moz-do-not-send="true" href="mailto:contact@brice.xyz"
                class="">contact@brice.xyz</a>> wrote:</div>
            <br class="Apple-interchange-newline">
            <div class="">
              <meta content="text/html; charset=utf-8"
                http-equiv="Content-Type" class="">
              <div bgcolor="#FFFFFF" text="#000000" class="">
                <p class="">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).</p>
                <p class="">Also, maybe managing this with classes
                  instead of syntax could also be done easily (without
                  any change to Python), like this: <br class="">
                </p>
                <p class=""><tt class="">from pyql import PQL, Select,
                    For, Where, GroupBy, Let</tt></p>
                <p class=""><tt class="">result = PQL(<br class="">
                        Select("x", "sum_y"),<br class="">
                        For</tt><tt class="">(</tt><tt class="">"x", </tt><tt
                    class="">range(</tt><tt class=""><span class="pl-c1">1</span></tt><tt
                    class="">,</tt><tt class=""><span class="pl-c1"> 8</span></tt><tt
                    class="">)</tt><tt class=""><span class="pl-k"></span></tt><tt
                    class=""><span class="pl-c1"></span></tt><tt
                    class=""><span class="pl-c1"></span></tt><tt
                    class=""><span class="pl-c1"></span></tt><tt
                    class="">),</tt><tt class=""><tt class=""><br
                        class="">
                          For</tt><tt class="">(</tt><tt class=""><span
                        class="pl-c1"></span></tt><tt class=""><span
                        class="pl-c1"></span></tt><tt class="">"</tt><tt
                      class="">y",</tt><tt class=""><span class="pl-k"></span></tt><tt
                      class=""> </tt><tt class=""><tt class="">range</tt>(</tt><tt
                      class=""><span class="pl-c1">1</span></tt><tt
                      class="">,</tt><tt class=""><span class="pl-c1"> 7</span></tt><tt
                      class="">)),<br class="">
                    </tt>    Where(</tt><tt class=""><tt class="">lambda
                      x, y: x </tt><tt class=""><span class="pl-k">%</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-c1">2</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-k">==</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-c1">0</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-k">and</span></tt><tt
                      class=""> y </tt><tt class=""><span class="pl-k">%</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-c1">2</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-k">!=</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-c1">0</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-k">and</span></tt><tt
                      class=""> x </tt><tt class=""><span class="pl-k">></span></tt><tt
                      class=""> y, </tt>"x", "y"</tt><tt class="">),</tt><tt
                    class="">  # function, *[arguments to pass to the
                    function]<br class="">
                        Where(</tt><tt class=""><tt class=""><tt
                        class=""><tt class="">"sum_y", </tt></tt>lambda
                    </tt></tt><tt class=""><tt class=""><tt class="">sum_y</tt>:
                    </tt></tt><tt class=""><tt class=""><tt class="">sum_y</tt>
                    </tt><tt class=""><span class="pl-k">%</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-c1">2</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-k">!=</span></tt><tt
                      class=""> </tt><tt class=""><span class="pl-c1">0</span></tt><tt
                      class="">)</tt></tt><br class="">
                  <tt class="">    GroupBy("x"),<br class="">
                        Let(</tt><tt class=""><tt class=""><tt class="">"sum_y",
                      </tt>lambda y: sum(y), "y"</tt>)</tt><tt class=""><br
                      class="">
                    )</tt></p>
                <div class=""><br class="">
                </div>
              </div>
            </div>
          </blockquote>
          <div><br class="">
          </div>
          So here’s the deal: small queries will look pretty decent in
          pretty much all paradigms, ORM, or PythonQL or your proposal.</div>
        <div>Once they get bigger and combine multiple pain points (say
          outerjoins, grouping and nested data) - then unless you have a</div>
        <div>really clear and minimal language, folks will get confused
          and lost.</div>
        <div><br class="">
        </div>
        <div>We’ve gone through a few query languages that failed,
          including XQuery and others, and the main reason was the need
          to learn</div>
        <div>a whole new language and a bunch of libraries, nobody
          wanted to do it. So the main selling point behind PythonQL is:
          its Python</div>
        <div>that folks hopefully know already, with just a few
          extensions.<br>
        </div>
      </div>
    </blockquote>
    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...<br>
    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:<br>
    <tt><br>
    </tt><tt>class MyPQL(PQL):</tt><tt><br>
    </tt><tt>    def get_limit(self):</tt><tt><br>
    </tt><tt>        if self.limit is not None:</tt><tt><br>
    </tt><tt>            return self.limit</tt><tt><br>
    </tt><tt><br>
    </tt><tt>        return 10</tt><tt><br>
    </tt><tt>    </tt><tt><br>
    </tt><tt>    def __init__(self, *args):</tt><tt><br>
    </tt><tt>        args.append(</tt><tt><span class="">Let(</span></tt><tt><span
        class=""><span class=""><span class="">"sum_y", </span>lambda
          y: sum(y), "y"</span>)</span></tt><tt><span class="">)</span></tt><tt><br>
    </tt><tt><span class="">        </span></tt><tt><span class=""><tt>args.append(</tt>GroupBy("x"))<br>
      </span></tt><tt>        super().__init__(*args)</tt><tt><br>
    </tt>
    <p class=""><tt><span class="">result = </span></tt><tt><span
          class=""><tt>MyPQL</tt>(<br class="">
              Select("x", "sum_y"),<br class="">
              For</span></tt><tt><span class="">(</span></tt><tt><span
          class="">"x", </span></tt><tt><span class="">range(</span></tt><tt><span
          class=""><span class="pl-c1">1</span></span></tt><tt><span
          class="">,</span></tt><tt><span class=""><span class="pl-c1">
            8</span></span></tt><tt><span class="">)</span></tt><tt><span
          class=""><span class="pl-k"></span></span></tt><tt><span
          class=""><span class="pl-c1"></span></span></tt><tt><span
          class=""><span class="pl-c1"></span></span></tt><tt><span
          class=""><span class="pl-c1"></span></span></tt><tt><span
          class="">),</span></tt><tt><span class=""><span class=""><br
              class="">
                For</span><span class="">(</span><span class=""><span
              class="pl-c1"></span></span><span class=""><span
              class="pl-c1"></span></span><span class="">"</span><span
            class="">y",</span><span class=""><span class="pl-k"></span></span><span
            class=""> </span><span class=""><span class="">range</span>(</span><span
            class=""><span class="pl-c1">1</span></span><span class="">,</span><span
            class=""><span class="pl-c1"> 7</span></span><span class="">)),<br
              class="">
          </span>    Where(</span></tt><tt><span class=""><span class="">lambda
            x, y: x </span><span class=""><span class="pl-k">%</span></span><span
            class=""> </span><span class=""><span class="pl-c1">2</span></span><span
            class=""> </span><span class=""><span class="pl-k">==</span></span><span
            class=""> </span><span class=""><span class="pl-c1">0</span></span><span
            class=""> </span><span class=""><span class="pl-k">and</span></span><span
            class=""> y </span><span class=""><span class="pl-k">%</span></span><span
            class=""> </span><span class=""><span class="pl-c1">2</span></span><span
            class=""> </span><span class=""><span class="pl-k">!=</span></span><span
            class=""> </span><span class=""><span class="pl-c1">0</span></span><span
            class=""> </span><span class=""><span class="pl-k">and</span></span><span
            class=""> x </span><span class=""><span class="pl-k">></span></span><span
            class=""> y, </span>"x", "y"</span></tt><tt><span class="">),</span></tt><tt><span
          class=""><br class="">
              Where(</span></tt><tt><span class=""><span class=""><span
              class=""><span class="">"sum_y", </span></span>lambda </span></span></tt><tt><span
          class=""><span class=""><span class="">sum_y</span>: </span></span></tt><tt><span
          class=""><span class=""><span class="">sum_y</span> </span><span
            class=""><span class="pl-k">%</span></span><span class=""> </span><span
            class=""><span class="pl-c1">2</span></span><span class="">
          </span><span class=""><span class="pl-k">!=</span></span><span
            class=""> </span><span class=""><span class="pl-c1">0</span></span><span
            class="">)</span></span></tt><tt><span class=""></span></tt><tt><span
          class=""><br class="">
          )</span></tt></p>
    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<tt><span class=""></span></tt><br>
    <tt><span class=""></span></tt>
    <p class=""><tt><span class="">where_from = [</span></tt><tt><span
          class="">For</span></tt><tt><span class="">(</span></tt><tt><span
          class="">"x", </span></tt><tt><span class="">range(</span></tt><tt><span
          class=""><span class="pl-c1">1</span></span></tt><tt><span
          class="">,</span></tt><tt><span class=""><span class="pl-c1">
            8</span></span></tt><tt><span class="">)</span></tt><tt><span
          class=""><span class="pl-k"></span></span></tt><tt><span
          class=""><span class="pl-c1"></span></span></tt><tt><span
          class=""><span class="pl-c1"></span></span></tt><tt><span
          class=""><span class="pl-c1"></span></span></tt><tt><span
          class="">),</span></tt><tt><span class=""><span class=""> For</span><span
            class="">(</span><span class=""><span class="pl-c1"></span></span><span
            class=""><span class="pl-c1"></span></span><span class="">"</span><span
            class="">y",</span><span class=""><span class="pl-k"></span></span><span
            class=""> </span><span class=""><span class="">range</span>(</span><span
            class=""><span class="pl-c1">1</span></span><span class="">,</span><span
            class=""><span class="pl-c1"> 7</span></span><span class="">))]</span></span></tt><tt><span
          class=""><br>
          where = [</span></tt><tt><span class="">Where(</span></tt><tt><span
          class=""><span class="">lambda x, y: x </span><span class=""><span
              class="pl-k">%</span></span><span class=""> </span><span
            class=""><span class="pl-c1">2</span></span><span class="">
          </span><span class=""><span class="pl-k">==</span></span><span
            class=""> </span><span class=""><span class="pl-c1">0</span></span><span
            class=""> </span><span class=""><span class="pl-k">and</span></span><span
            class=""> y </span><span class=""><span class="pl-k">%</span></span><span
            class=""> </span><span class=""><span class="pl-c1">2</span></span><span
            class=""> </span><span class=""><span class="pl-k">!=</span></span><span
            class=""> </span><span class=""><span class="pl-c1">0</span></span><span
            class=""> </span><span class=""><span class="pl-k">and</span></span><span
            class=""> x </span><span class=""><span class="pl-k">></span></span><span
            class=""> y, </span>"x", "y"</span></tt><tt><span class="">)</span></tt><tt><span
          class=""></span></tt><tt><span class="">]<br>
          if filter_sum_y:<br>
              </span></tt><tt><span class=""><tt><span class="">where</span></tt>.append(</span></tt><tt><span
          class=""><tt><span class="">Where(</span></tt><tt><span
              class=""><span class=""><span class=""><span class="">"sum_y",
                  </span></span>lambda </span></span></tt><tt><span
              class=""><span class=""><span class="">sum_y</span>: </span></span></tt><tt><span
              class=""><span class=""><span class="">sum_y</span> </span><span
                class=""><span class="pl-k">%</span></span><span
                class=""> </span><span class=""><span class="pl-c1">2</span></span><span
                class=""> </span><span class=""><span class="pl-k">!=</span></span><span
                class=""> </span><span class=""><span class="pl-c1">0</span></span><span
                class="">)</span></span></tt><tt><span class=""></span></tt><tt><span
              class=""></span></tt>)<br>
        </span></tt><tt><span class=""><span class=""><br>
          </span></span></tt><tt><span class=""><span class=""><tt><span
                class="">if group_by is not None:<br>
              </span></tt>    grouping = </span></span></tt><tt><span
          class=""></span></tt><tt><span class="">GroupBy("x")</span></tt><br>
    </p>
    <p class=""><tt><span class="">result = </span></tt><tt><span
          class=""><tt>MyPQL</tt>(</span></tt><tt><span class=""><tt><span
              class="">Select("x", "sum_y")</span></tt>, *where_from,
          *where, *grouping)</span></tt></p>
    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).<br>
    <br>
    -Brice<br>
  </body>
</html>