📄 query.py
字号:
(user10, 0, "Name:chuck")] # test with a straight statement s = select([users, func.count(addresses.c.id).label('count'), ("Name:" + users.c.name).label('concat')], from_obj=[users.outerjoin(addresses)], group_by=[c for c in users.c], order_by=[users.c.id]) q = create_session().query(User) l = q.add_column("count").add_column("concat").from_statement(s).all() assert l == expected sess.clear() # test with select_from() q = create_session().query(User).add_column(func.count(addresses.c.id))\ .add_column(("Name:" + users.c.name)).select_from(users.outerjoin(addresses))\ .group_by([c for c in users.c]).order_by(users.c.id) assert q.all() == expected sess.clear() # test with outerjoin() both aliased and non for aliased in (False, True): q = create_session().query(User).add_column(func.count(addresses.c.id))\ .add_column(("Name:" + users.c.name)).outerjoin('addresses', aliased=aliased)\ .group_by([c for c in users.c]).order_by(users.c.id) assert q.all() == expected sess.clear()class SelectFromTest(QueryTest): keep_mappers = False def setup_mappers(self): pass def test_replace_with_select(self): mapper(User, users, properties = { 'addresses':relation(Address) }) mapper(Address, addresses) sel = users.select(users.c.id.in_([7, 8])).alias() sess = create_session() self.assertEquals(sess.query(User).select_from(sel).all(), [User(id=7), User(id=8)]) self.assertEquals(sess.query(User).select_from(sel).filter(User.c.id==8).all(), [User(id=8)]) self.assertEquals(sess.query(User).select_from(sel).order_by(desc(User.name)).all(), [ User(name='jack',id=7), User(name='ed',id=8) ]) self.assertEquals(sess.query(User).select_from(sel).order_by(asc(User.name)).all(), [ User(name='ed',id=8), User(name='jack',id=7) ]) self.assertEquals(sess.query(User).select_from(sel).options(eagerload('addresses')).first(), User(name='jack', addresses=[Address(id=1)]) ) def test_join(self): mapper(User, users, properties = { 'addresses':relation(Address) }) mapper(Address, addresses) sel = users.select(users.c.id.in_([7, 8])) sess = create_session() self.assertEquals(sess.query(User).select_from(sel).join('addresses').add_entity(Address).order_by(User.id).order_by(Address.id).all(), [ (User(name='jack',id=7), Address(user_id=7,email_address='jack@bean.com',id=1)), (User(name='ed',id=8), Address(user_id=8,email_address='ed@wood.com',id=2)), (User(name='ed',id=8), Address(user_id=8,email_address='ed@bettyboop.com',id=3)), (User(name='ed',id=8), Address(user_id=8,email_address='ed@lala.com',id=4)) ] ) self.assertEquals(sess.query(User).select_from(sel).join('addresses', aliased=True).add_entity(Address).order_by(User.id).order_by(Address.id).all(), [ (User(name='jack',id=7), Address(user_id=7,email_address='jack@bean.com',id=1)), (User(name='ed',id=8), Address(user_id=8,email_address='ed@wood.com',id=2)), (User(name='ed',id=8), Address(user_id=8,email_address='ed@bettyboop.com',id=3)), (User(name='ed',id=8), Address(user_id=8,email_address='ed@lala.com',id=4)) ] ) def test_more_joins(self): mapper(User, users, properties={ 'orders':relation(Order, backref='user'), # o2m, m2o }) mapper(Order, orders, properties={ 'items':relation(Item, secondary=order_items, order_by=items.c.id), #m2m }) mapper(Item, items, properties={ 'keywords':relation(Keyword, secondary=item_keywords, order_by=keywords.c.id) #m2m }) mapper(Keyword, keywords) sel = users.select(users.c.id.in_([7, 8])) sess = create_session() self.assertEquals(sess.query(User).select_from(sel).join(['orders', 'items', 'keywords']).filter(Keyword.name.in_(['red', 'big', 'round'])).all(), [ User(name=u'jack',id=7) ]) self.assertEquals(sess.query(User).select_from(sel).join(['orders', 'items', 'keywords'], aliased=True).filter(Keyword.name.in_(['red', 'big', 'round'])).all(), [ User(name=u'jack',id=7) ]) def go(): self.assertEquals(sess.query(User).select_from(sel).options(eagerload_all('orders.items.keywords')).join(['orders', 'items', 'keywords'], aliased=True).filter(Keyword.name.in_(['red', 'big', 'round'])).all(), [ User(name=u'jack',orders=[ Order(description=u'order 1',items=[ Item(description=u'item 1',keywords=[Keyword(name=u'red'), Keyword(name=u'big'), Keyword(name=u'round')]), Item(description=u'item 2',keywords=[Keyword(name=u'red',id=2), Keyword(name=u'small',id=5), Keyword(name=u'square')]), Item(description=u'item 3',keywords=[Keyword(name=u'green',id=3), Keyword(name=u'big',id=4), Keyword(name=u'round',id=6)]) ]), Order(description=u'order 3',items=[ Item(description=u'item 3',keywords=[Keyword(name=u'green',id=3), Keyword(name=u'big',id=4), Keyword(name=u'round',id=6)]), Item(description=u'item 4',keywords=[],id=4), Item(description=u'item 5',keywords=[],id=5) ]), Order(description=u'order 5',items=[Item(description=u'item 5',keywords=[])])]) ]) self.assert_sql_count(testing.db, go, 1) sess.clear() sel2 = orders.select(orders.c.id.in_([1,2,3])) self.assertEquals(sess.query(Order).select_from(sel2).join(['items', 'keywords']).filter(Keyword.name == 'red').all(), [ Order(description=u'order 1',id=1), Order(description=u'order 2',id=2), ]) self.assertEquals(sess.query(Order).select_from(sel2).join(['items', 'keywords'], aliased=True).filter(Keyword.name == 'red').all(), [ Order(description=u'order 1',id=1), Order(description=u'order 2',id=2), ]) def test_replace_with_eager(self): mapper(User, users, properties = { 'addresses':relation(Address) }) mapper(Address, addresses) sel = users.select(users.c.id.in_([7, 8])) sess = create_session() def go(): self.assertEquals(sess.query(User).options(eagerload('addresses')).select_from(sel).all(), [ User(id=7, addresses=[Address(id=1)]), User(id=8, addresses=[Address(id=2), Address(id=3), Address(id=4)]) ] ) self.assert_sql_count(testing.db, go, 1) sess.clear() def go(): self.assertEquals(sess.query(User).options(eagerload('addresses')).select_from(sel).filter(User.c.id==8).all(), [User(id=8, addresses=[Address(id=2), Address(id=3), Address(id=4)])] ) self.assert_sql_count(testing.db, go, 1) sess.clear() def go(): self.assertEquals(sess.query(User).options(eagerload('addresses')).select_from(sel)[1], User(id=8, addresses=[Address(id=2), Address(id=3), Address(id=4)])) self.assert_sql_count(testing.db, go, 1)class CustomJoinTest(QueryTest): keep_mappers = False def setup_mappers(self): pass def test_double_same_mappers(self): """test aliasing of joins with a custom join condition""" mapper(Address, addresses) mapper(Order, orders, properties={ 'items':relation(Item, secondary=order_items, lazy=True, order_by=items.c.id), }) mapper(Item, items) mapper(User, users, properties = dict( addresses = relation(Address, lazy=True), open_orders = relation(Order, primaryjoin = and_(orders.c.isopen == 1, users.c.id==orders.c.user_id), lazy=True), closed_orders = relation(Order, primaryjoin = and_(orders.c.isopen == 0, users.c.id==orders.c.user_id), lazy=True) )) q = create_session().query(User) assert [User(id=7)] == q.join(['open_orders', 'items'], aliased=True).filter(Item.id==4).join(['closed_orders', 'items'], aliased=True).filter(Item.id==3).all()class SelfReferentialJoinTest(ORMTest): def define_tables(self, metadata): global nodes nodes = Table('nodes', metadata, Column('id', Integer, primary_key=True), Column('parent_id', Integer, ForeignKey('nodes.id')), Column('data', String(30))) def test_join(self): class Node(Base): def append(self, node): self.children.append(node) mapper(Node, nodes, properties={ 'children':relation(Node, lazy=True, join_depth=3, backref=backref('parent', remote_side=[nodes.c.id]) ) }) sess = create_session() n1 = Node(data='n1') n1.append(Node(data='n11')) n1.append(Node(data='n12')) n1.append(Node(data='n13')) n1.children[1].append(Node(data='n121')) n1.children[1].append(Node(data='n122')) n1.children[1].append(Node(data='n123')) sess.save(n1) sess.flush() sess.clear() # TODO: the aliasing of the join in query._join_to has to limit the aliasing # among local_side / remote_side (add local_side as an attribute on PropertyLoader) # also implement this idea in EagerLoader node = sess.query(Node).join('children', aliased=True).filter_by(data='n122').first() assert node.data=='n12' node = sess.query(Node).join(['children', 'children'], aliased=True).filter_by(data='n122').first() assert node.data=='n1' node = sess.query(Node).filter_by(data='n122').join('parent', aliased=True).filter_by(data='n12').\ join('parent', aliased=True, from_joinpoint=True).filter_by(data='n1').first() assert node.data == 'n122'class ExternalColumnsTest(QueryTest): keep_mappers = False def setup_mappers(self): pass def test_external_columns_bad(self): """test that SA catches some common mis-configurations of external columns.""" f = (users.c.id * 2) try: mapper(User, users, properties={ 'concat': f, }) class_mapper(User) except exceptions.ArgumentError, e: assert str(e) == "Column '%s' is not represented in mapper's table. Use the `column_property()` function to force this column to be mapped as a read-only attribute." % str(f) else: raise 'expected ArgumentError' clear_mappers() try: mapper(User, users, properties={ 'count': column_property(select([func.count(addresses.c.id)], users.c.id==addresses.c.user_id).correlate(users)) }) except exceptions.ArgumentError, e: assert str(e) == 'column_property() must be given a ColumnElement as its argument. Try .label() or .as_scalar() for Selectables to fix this.' else: raise 'expected ArgumentError' def test_external_columns_good(self): """test querying mappings that reference external columns or selectables.""" mapper(User, users, properties={ 'concat': column_property((users.c.id * 2)), 'count': column_property(select([func.count(addresses.c.id)], users.c.id==addresses.c.user_id).correlate(users).as_scalar()) }) mapper(Address, addresses, properties={ 'user':relation(User, lazy=True) }) sess = create_session() l = sess.query(User).all() assert [ User(id=7, concat=14, count=1), User(id=8, concat=16, count=3), User(id=9, concat=18, count=1), User(id=10, concat=20, count=0), ] == l address_result = [ Address(id=1, user=User(id=7, concat=14, count=1)), Address(id=2, user=User(id=8, concat=16, count=3)), Address(id=3, user=User(id=8, concat=16, count=3)), Address(id=4, user=User(id=8, concat=16, count=3)), Address(id=5, user=User(id=9, concat=18, count=1)) ] assert address_result == sess.query(Address).all() # run the eager version twice to test caching of aliased clauses for x in range(2): sess.clear() def go(): assert address_result == sess.query(Address).options(eagerload('user')).all() self.assert_sql_count(testing.db, go, 1) tuple_address_result = [(address, address.user) for address in address_result] tuple_address_result == sess.query(Address).join('user').add_entity(User).all() assert tuple_address_result == sess.query(Address).join('user', aliased=True, id='ualias').add_entity(User, id='ualias').all()if __name__ == '__main__': testenv.main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -