]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
small fix for filter() aliasing, upgraded elementtree examples to use 0.4 style queries
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 3 Aug 2007 18:47:35 +0000 (18:47 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 3 Aug 2007 18:47:35 +0000 (18:47 +0000)
examples/elementtree/adjacency_list.py
examples/elementtree/optimized_al.py
lib/sqlalchemy/orm/util.py
test/orm/query.py

index 204662f5615a7e865cfd7c2de39a1a2fb148ba3a..af9084a44888ef692d01031b255ce725b399b9d6 100644 (file)
@@ -26,7 +26,7 @@ from elementtree import ElementTree
 from elementtree.ElementTree import Element, SubElement
 
 meta = MetaData()
-meta.engine = 'sqlite://'
+meta.bind = 'sqlite://'
 
 ################################# PART II - Table Metadata ###########################################
     
@@ -174,12 +174,10 @@ print document
 ############################################ PART VI - Searching for Paths #######################################
 
 # manually search for a document which contains "/somefile/header/field1:hi"
-print "\nManual search for /somefile/header/field1=='hi':", line
-n1 = elements.alias('n1')
-n2 = elements.alias('n2')
-n3 = elements.alias('n3')
-j = documents.join(n1).join(n2, n1.c.element_id==n2.c.parent_id).join(n3, n2.c.element_id==n3.c.parent_id)
-d = session.query(Document).select_from(j).filter(n1.c.tag=='somefile').filter(n2.c.tag=='header').filter(and_(n3.c.tag=='field1', n3.c.text=='hi')).one()
+d = session.query(Document).join('_root', aliased=True).filter(_Node.tag=='somefile').\
+    join('children', aliased=True, from_joinpoint=True).filter(_Node.tag=='header').\
+    join('children', aliased=True, from_joinpoint=True).filter(and_(_Node.tag=='field1', _Node.text=='hi')).\
+    one()
 print d
 
 # generalize the above approach into an extremely impoverished xpath function:
@@ -187,22 +185,17 @@ def find_document(path, compareto):
     j = documents
     prev_elements = None
     query = session.query(Document)
+    attribute = '_root'
     for i, match in enumerate(re.finditer(r'/([\w_]+)(?:\[@([\w_]+)(?:=(.*))?\])?', path)):
         (token, attrname, attrvalue) = match.group(1, 2, 3)
-        a = elements.alias("n%d" % i)
-        query = query.filter(a.c.tag==token)
+        query = query.join(attribute, aliased=True, from_joinpoint=True).filter(_Node.tag==token)
+        attribute = 'children'
         if attrname:
-            attr_alias = attributes.alias('a%d' % i)
             if attrvalue:
-                query = query.filter(and_(a.c.element_id==attr_alias.c.element_id, attr_alias.c.name==attrname, attr_alias.c.value==attrvalue))
+                query = query.join('attributes', aliased=True, from_joinpoint=True).filter(and_(_Attribute.name==attrname, _Attribute.value==attrvalue))
             else:
-                query = query.filter(and_(a.c.element_id==attr_alias.c.element_id, attr_alias.c.name==attrname))
-        if prev_elements is not None:
-            j = j.join(a, prev_elements.c.element_id==a.c.parent_id)
-        else:
-            j = j.join(a)
-        prev_elements = a
-    return query.options(lazyload('_root')).select_from(j).filter(prev_elements.c.text==compareto).all()
+                query = query.join('attributes', aliased=True, from_joinpoint=True).filter(_Attribute.name==attrname)
+    return query.options(lazyload('_root')).filter(_Node.text==compareto).all()
 
 for path, compareto in (
         ('/somefile/header/field1', 'hi'),
index 17b6489de05667708b68ced7ad07ee647b44443f..5666f879a1705273d1fa5111f1c21b6f28e6922a 100644 (file)
@@ -18,14 +18,14 @@ logging.basicConfig()
 #logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
 
 # uncomment to show SQL statements and result sets
-logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
+#logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
 
 
 from elementtree import ElementTree
 from elementtree.ElementTree import Element, SubElement
 
 meta = MetaData()
-meta.engine = 'sqlite://'
+meta.bind = 'sqlite://'
 
 ################################# PART II - Table Metadata ###########################################
     
@@ -94,7 +94,7 @@ mapper(Document, documents, properties={
 })
 
 # the _Node objects change the way they load so that a list of _Nodes will organize
-# themselves hierarchically using the HierarchicalLoader.  this depends on the ordering of
+# themselves hierarchically using the ElementTreeMarshal.  this depends on the ordering of
 # nodes being hierarchical as well; relation() always applies at least ROWID/primary key
 # ordering to rows which will suffice.
 mapper(_Node, elements, properties={
@@ -184,11 +184,10 @@ print document
 
 # manually search for a document which contains "/somefile/header/field1:hi"
 print "\nManual search for /somefile/header/field1=='hi':", line
-n1 = elements.alias('n1')
-n2 = elements.alias('n2')
-n3 = elements.alias('n3')
-j = documents.join(n1).join(n2, n1.c.element_id==n2.c.parent_id).join(n3, n2.c.element_id==n3.c.parent_id)
-d = session.query(Document).select_from(j).filter(n1.c.tag=='somefile').filter(n2.c.tag=='header').filter(and_(n3.c.tag=='field1', n3.c.text=='hi')).one()
+d = session.query(Document).join('_nodes', aliased=True).filter(and_(_Node.parent_id==None, _Node.tag=='somefile')).\
+    join('children', aliased=True, from_joinpoint=True).filter(_Node.tag=='header').\
+    join('children', aliased=True, from_joinpoint=True).filter(and_(_Node.tag=='field1', _Node.text=='hi')).\
+    one()
 print d
 
 # generalize the above approach into an extremely impoverished xpath function:
@@ -196,22 +195,22 @@ def find_document(path, compareto):
     j = documents
     prev_elements = None
     query = session.query(Document)
+    first = True
     for i, match in enumerate(re.finditer(r'/([\w_]+)(?:\[@([\w_]+)(?:=(.*))?\])?', path)):
         (token, attrname, attrvalue) = match.group(1, 2, 3)
-        a = elements.alias("n%d" % i)
-        query = query.filter(a.c.tag==token)
+        if first:
+            query = query.join('_nodes', aliased=True).filter(_Node.parent_id==None)
+            first = False
+        else:
+            query = query.join('children', aliased=True, from_joinpoint=True)
+        query = query.filter(_Node.tag==token)
         if attrname:
-            attr_alias = attributes.alias('a%d' % i)
+            query = query.join('attributes', aliased=True, from_joinpoint=True)
             if attrvalue:
-                query = query.filter(and_(a.c.element_id==attr_alias.c.element_id, attr_alias.c.name==attrname, attr_alias.c.value==attrvalue))
+                query = query.filter(and_(_Attribute.name==attrname, _Attribute.value==attrvalue))
             else:
-                query = query.filter(and_(a.c.element_id==attr_alias.c.element_id, attr_alias.c.name==attrname))
-        if prev_elements is not None:
-            j = j.join(a, prev_elements.c.element_id==a.c.parent_id)
-        else:
-            j = j.join(a)
-        prev_elements = a
-    return query.options(lazyload('_nodes')).select_from(j).filter(prev_elements.c.text==compareto).all()
+                query = query.filter(_Attribute.name==attrname)
+    return query.options(lazyload('_nodes')).filter(_Node.text==compareto).all()
 
 for path, compareto in (
         ('/somefile/header/field1', 'hi'),
index 727be50c61deed9802458f980e4ada70ee683734..e9fe6ac4ef4d09db9c42b97fc1a5ae3dac448a7c 100644 (file)
@@ -211,8 +211,7 @@ class AliasedClauses(object):
         return aliased_column
 
     def adapt_clause(self, clause):
-        return self.aliased_column(clause)
-#        return sql_util.ClauseAdapter(self.alias).traverse(clause, clone=True)
+        return sql_util.ClauseAdapter(self.alias).traverse(clause, clone=True)
     
     def _create_row_adapter(self):
         """Return a callable which, 
index 3c9d143201d36de6ba492b14b166baa2ebfd9f36..e01c0e67d876befc0bd27bcd1e5683b5787e9865 100644 (file)
@@ -421,6 +421,9 @@ class JoinTest(QueryTest):
         q = sess.query(User).join('addresses', aliased=True).filter(Address.email_address=='jack@bean.com')
         assert [User(id=7)] == q.all()
 
+        q = sess.query(User).join('addresses', aliased=True).filter(or_(Address.email_address=='jack@bean.com', Address.email_address=='fred@fred.com'))
+        assert [User(id=7), User(id=9)] == q.all()
+
         # test two aliasized paths, one to 'orders' and the other to 'orders','items'.
         # one row is returned because user 7 has order 3 and also has order 1 which has item 1
         # this tests a o2m join and a m2m join.