2010-02-07 62 views
0

我有一个多对多的关系,其中关系表包含的列数多于只有主键。作为一个例子,考虑一个幻灯片放映系统,其中每个图像可能有自己的超时时间,并根据幻灯片显示不同的超时时间。一个愚蠢的例子,但它会为说明起见做;)使用SQLAlchemy检索多对多关系属性

所以我想我会做类似如下(使用声明):

show_has_image = Table('show_has_image', 
     DeclarativeBase.metadata, 
     Column('show_id', Integer, ForeignKey('show.id')), 
     Column('image_id', Integer, ForeignKey('image.id')), 
     Column('timeout', Integer, default=5), 
     PrimaryKeyConstraint('show_id', 'image_id') 
    ) 

class Show(DeclarativeBase): 
    __tablename__ = "show" 

    id = Column(Integer, primary_key = True) 
    name = Column(Unicode(64), nullable = False) 

class Image(DeclarativeBase): 
    __tablename__ = "image" 

    id = Column(Integer, primary_key = True) 
    name = Column(Unicode(64), nullable = False) 
    data = Column(Binary, nullable = True) 
    show = relation("Show", 
     secondary=show_has_image, 
     backref="images") 

我怎么会进入“超时“价值?我在文档中找不到关于此的任何内容。 到目前为止,检索图片很简单:

show = DBSession.query(Show).filter_by(id=show_id).one() 
for image in show.images: 
    print image.name 
    # print image.timeout <--- Obviously this cannot work, as SA has no idea 
    #       how to map this field. 

我会更乐意有它的工作我只是在前面的代码中概述的方式。当然,我可以添加一个timeout属性到Image类,它将动态获取值。但是这会导致不必要的SQL查询。

我宁愿将它全部返回到一个查询中。在SQL中很容易:

SELECT i.name, si.timeout 
     FROM show s 
INNER JOIN show_has_image si ON (si.show_id = s.id) 
INNER JOIN image i ON (si.image_id = i.id) 
    WHERE s.id = :show_id 

回答

1

您可以根据show_has_image表(使用复合主键)定义中间模型并定义它与之的关系。然后使用association_proxy来定义Show.images属性。

+0

这似乎是沿着我所寻找的线。不幸的是,它在Turbogears中打破了“猫步”。因为 - 在目前的应用程序状态 - 我依靠时装表演,我还不能使用这个。但我稍后再看看。如果应用程序超过了第一个“概念验证”演示。 – exhuma 2010-03-22 16:37:29