2011-05-19 29 views
1

我有两个表项和ItemDescriptions如何根据SqlAlchemy中的表B选择表A中的一个?

class Item(Base): 
    __tablename__ = "item" 
    id = Column(Integer, primary_key=True) 
    description_id = Column(Integer, ForeignKey('item_description.id')) 

class ItemDescription(Base): 
    __tablename__ = "item_description" 
    id = Column(Integer, primary_key=True) 

鉴于ItemDescriptions我想这样的项目有每个ItemDescription ID的一个项目的名单列表。我不在乎哪个项目。

[编辑为清晰起见]

鉴于项目和说明的这个名单:

Item, Description 
1 , 1 
2 , 1 
3 , 1 
4 , 2 
5 , 2 
6 , 3 
7 , 3 
8 , 3 

我想要一个查询,将返回类似:

Item, Description 
2 , 1 
4 , 2 
7 , 3 

我无法完成子查询等。

谢谢你的帮助

回答

2

我是column_property的忠实粉丝。这里有一种方法可以用column_property来做你想做的事情:

from sqlalchemy import * 
from sqlalchemy.orm import * 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

class Item(Base): 
    __tablename__ = 'item' 

    id = Column(Integer, primary_key=True) 
    description_id = Column(Integer, ForeignKey('item_description.id')) 

class ItemDescription(Base): 
    __tablename__ = 'item_description' 

    id = Column(Integer, primary_key=True) 

    any_item_id = column_property(
     select(
      [Item.id], 
      id == Item.description_id, 
      limit=1, 
     ).label('any_item_id'), 
     deferred=True, 
    ) 

e = create_engine('sqlite://', echo=True) 
Base.metadata.create_all(e) 

s = Session(e) 

descriptions = [ 
    ItemDescription(id=1), 
    ItemDescription(id=2), 
    ItemDescription(id=3), 
] 

s.add_all(descriptions) 

items = [ 
    Item(id=1, description_id=1), 
    Item(id=2, description_id=1), 
    Item(id=3, description_id=1), 
    Item(id=4, description_id=2), 
    Item(id=5, description_id=2), 
    Item(id=6, description_id=3), 
    Item(id=7, description_id=3), 
    Item(id=8, description_id=3), 
] 

s.add_all(items) 

query = s.query(ItemDescription).options(undefer('any_item_id')) 
for description in query: 
    print description.any_item_id, description.id 

# alternative way without using column_property 
query = s.query(
    select(
     [Item.id], 
     ItemDescription.id == Item.description_id, 
     limit=1, 
    ).label('any_item_id'), 
    ItemDescription, 
) 
for item_id, description in query: 
    print item_id, description.id 
+0

column_property看起来不错,谢谢!如果我想把它作为单个查询而不是列属性,我会把select放在子查询中吗? – Ben 2011-05-20 21:11:50

+0

是的,你可以将选择移动到查询中。我已经添加了答案。就个人而言,我仍然更喜欢column_property :) – sayap 2011-05-21 01:20:12

+0

我喜欢column_query方法,但也感谢您以查询方式显示。 – Ben 2011-05-24 17:50:48

0
from sqlalchemy.orm import relationship, backref 

class Item(Base): 
    __tablename__ = "item" 
    id = Column(Integer, primary_key=True) 
    description_id = Column(Integer, ForeignKey('item_description.id')) 
    desc = relationship(User, backref=backref('desc', order_by=id)) 

class ItemDescription(Base): 
    __tablename__ = "item_description" 
    id = Column(Integer, primary_key=True) 

Now your every ItemDescription class will have an backref called `desc` which is nothing but a list of Item. 

Now you can do something like this 

item_desc = session.query(ItemDescription).\ 
...      options(joinedload('desc').all() 

for item in item_desc: 
    print item.desc 

我想这可能不会给你确切的答案。它会帮助我猜

+0

对不起,我的解释不是很清楚,我会编辑它以使其更清晰。 – Ben 2011-05-19 22:41:40

相关问题