<div dir="ltr">Yes, I've found the .filter() method in sources but not found it in the documentation, thank you for your explanations. It would be good and enough replacement for intersection.<div><br></div><div>Just one inconvinience with .filter() is that the lambda parameter name actually is not used to desemble an expression, and the previously used generator parameter is used in lambda instead (the following example uses djony wrapper):</div>
<div><br></div><div><br></div><div><div>>>> with orm.db_session:</div><div>...  users = orm.select(u for u in User.p)</div><div>...  me = users.filter(lambda u: u.username == 'seva')</div><div>...  for u in me: print u.username</div>
<div>... </div><div>seva</div><div>>>> with orm.db_session:</div><div>...  users = orm.select(u for u in User.p)</div><div>...  me = users.filter(lambda usr: usr.username == 'seva')</div><div>...  for u in me: print u.username</div>
<div>... </div><div>Traceback (most recent call last):</div><div>  File "<console>", line 3, in <module></div><div>  File "<string>", line 2, in filter</div><div>  File "/usr/local/lib/python2.7/dist-packages/pony/utils.py", line 95, in cut_traceback</div>
<div>    return func(*args, **kwargs)</div><div>  File "/usr/local/lib/python2.7/dist-packages/pony/orm/core.py", line 4030, in filter</div><div>    throw(TranslationError, 'Unknown name %s' % name)</div>
<div>  File "/usr/local/lib/python2.7/dist-packages/pony/utils.py", line 121, in throw</div><div>    raise exc</div><div>TranslationError: Unknown name usr</div></div><div><br></div><div style>As you can see, the first code block uses the same parameter name in generator and lambda and works fine, while the second one uses different names and fails with exception, being fine from the point of labda syntax and semantic view.</div>
<div style><br></div><div style>This inconvinience leads to difficulties in code isolation (lambda writer should know name of the generator parameter, which might be hidden in other subsystem written by other team).</div>
<div style><br></div><div style>Is this inconvinience particularly one which you meant, or something other?</div><div style><br></div><div style>As for the intersection, union and subtraction, these functions might be constructed using logic combinations of filter expressions in involved queries instead of using special SQL syntax to implement them IMHO (and that is really what I meant before).</div>
<div style><br></div><div style>The only problem is analysing source records domain for both queries involved to set expression. It might be fine restriction if you restrict such expressions only for the same source record domains for both queries, and use special UNION expression for different domains, mapped directly to standard UNION expression of SQL.</div>
<div style><br></div><div style>For example:</div><div style>select(d for d in Document if some_keyword in d.keywords) <b>&</b></div><div style>select(d for d in Document if d.owner == some_user)</div><div style><br></div>
<div style>is converted to (SQL)</div><div style>SELECT * FROM Document WHERE keywords like CONCAT('%',$some_keyword,'%') <b>AND</b> owner = $some_user<br></div><div><br></div><div style>While</div><div style>
<br></div><div><div>select(d for d in Document if some_keyword in d.keywords) <b>|</b></div><div>select(d for d in Document if d.owner == some_user)</div><div><br></div><div>is converted to</div><div><div>SELECT * FROM Document WHERE keywords like CONCAT('%',$some_keyword,'%') <b>OR</b> owner = $some_user<br>
</div></div></div><div><br></div><div style>But</div><div style><div>select(d for d in Document if some_keyword in d.keywords)<b>.union(</b></div><div>select(d for d in Document if d.owner == some_user))</div><div><br></div>
<div><div>is converted to</div><div>SELECT * FROM Document WHERE keywords like CONCAT('%',$some_keyword,'%')</div><div style>UNION</div><div>SELECT * FROM Document WHERE owner = $some_user</div></div></div>
<div><br></div><div style>The first two cases might be implemented easy using existent .filter() functionality.</div><div><br></div><div style>Regards,</div><div style>Vsevolod</div><div style><br></div><div><br></div></div>
<div class="gmail_extra"><br><br><div class="gmail_quote">2013/10/21 Alexander Kozlovsky <span dir="ltr"><<a href="mailto:alexander.kozlovsky@gmail.com" target="_blank">alexander.kozlovsky@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Hi Vsevolod!<div><br></div><div>I think it is possible to implement this feature in Pony ORM with the following API:<br><br>q1 = select(s for s in Student if ...)<br>q2 = select(s for s in Student if ...)<br>


q3 = q1.union(q2)<br>q4 = q1.intersect(q2)<br>q5 = q1.except(q2)<br><br>The implementation will take 3-5 work days (or may be longer, because MySQL has no direct support of INTERSECT and EXCEPT and requires to write a workaround via joins), and currently we have more urgent tasks (such as migration support), so I don't think this feature can be implemented during this year. Please add this feature to our issue list on GitHub, and we'll implement it when time permits.</div>


<div><br></div><div>By the way, I fear that some programmers may overuse such 'algebra' and as a result construct inefficient queries. Let's consider the next query:</div><div><br></div><div>SELECT * FROM T1 WHERE X > 100</div>


<div>INTERSECT</div><div>SELECT * FROM T1 WHERE Y < 200</div><div><br></div><div>In many situations, the next equivalent query will be faster:<br><br>SELECT * FROM T1 WHERE X > 100 and Y < 200</div><div><br></div>


<div>So in case of implementing user-restricted document search, it may be more efficient to implement it in the following way, via incremental filtering of the same query:</div><div><br></div><div><div>def document_search(current_user, specified_keyword=None,</div>


<div>        part_of_title=None, document_type=None,</div><div>        min_size=None, max_size=None):<br></div><div><br></div>    query = select(d for d in Documents</div><div>        if d.owner == current_user or current_user in d.editors)</div>


<div><div><br></div><div>    if specified_keyword is not None:</div>        query.filter(lambda d: specified_keyword in d.keywords)</div><div><br></div><div>    if part_of_title is not None:</div><div>        query.filter(lambda d: part_of_title in d.title)</div>


<div><br></div><div>    if document_type is not None:<br></div><div>        query.filter(lambda d: d.type = document_type)</div><div><br></div><div>    if min_size is not None:</div><div>        query.filter(lambda d: d.size >= min_size)</div>


<div><div><br></div><div>    if max_size is not None:</div><div>        query.filter(lambda d: d.size <= max_size)</div></div><div><br></div><div>    return query<br><br>This way of filtering should works in the development version of Pony (it was accidentally broken in the last release 0.4.8, but will be restored in the upcoming release 0.4.9)</div>


<div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div class="h5">On Mon, Oct 21, 2013 at 2:27 PM, Vsevolod Novikov <span dir="ltr"><<a href="mailto:nnseva@gmail.com" target="_blank">nnseva@gmail.com</a>></span> wrote:<br>


</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr">Hi All,<div><br></div><div><div>It would be useful to implement some kind of 'algebra of sets': intersection, union, and subtraction of sets defined by two abstract queries.</div>


<div><br></div>
<div>Let I am writing a subsystem which should accept some queries A and B and do something with it's intersection. Is it possible someway?</div><div><br></div><div>The particular (simplified) usecase: Let we have Users, Groups, and Documents belonging to User (individual), or Group (shared).</div>



<div><br></div><div>We have wrote a 'user access' subsystem which restricts access to Documents and returns some DocumentSet (query?) object (document_set_a) which refers to all Documents belonging to this User directly or through the Group.</div>



<div><br></div><div>Also we have wrote some other subsystem, let it be 'document index', which returns other DocumentSet (query?) object (document_set_b) which refers to all Documents containing passed keywords.</div>



<div><br></div><div>Now we want to write user-restricted document index: the user passes us keywords and wants to see all Documents belonging to him and containing these keywords. So we should return a DocumentSet which is an intersection of document_set_a and document_set_b.</div>



<div><br></div><div>Regards,</div><div>Vsevolod</div><div><br></div></div></div>
<br></div></div>_______________________________________________<br>
ponyorm-list mailing list<br>
<a href="mailto:ponyorm-list@ponyorm.org" target="_blank">ponyorm-list@ponyorm.org</a><br>
<a href="/ponyorm-list" target="_blank">/ponyorm-list</a><br>
<br></blockquote></div><br></div>
<br>_______________________________________________<br>
ponyorm-list mailing list<br>
<a href="mailto:ponyorm-list@ponyorm.org">ponyorm-list@ponyorm.org</a><br>
<a href="/ponyorm-list" target="_blank">/ponyorm-list</a><br>
<br></blockquote></div><br></div>