SQLAlchemy:使用id而不是object添加关系?

时间:2011-05-16 23:14:09

标签: python orm sqlalchemy relationship

是否可以使用ids而不是对象添加到SQLAlchemy关系?

例如,考虑两个声明性SQLAlchemy类,Review和Artist,以及它们之间的关系:

class Review(Base):
    artist_id = Column(Integer, ForeignKey('artist.id'))
    artist = relationship(Artist, backref=backref('reviews', order_by=id))
    # etc.

class Artist(Base):
    # etc.

使用要添加到艺术家的评论ID列表,我似乎需要从ID中查找艺术家,然后将艺术家对象添加到评论中,如下所示:

for review_id in review_ids:
    review = session.query(Review).filter(Review.id==review_id).first()
    artist.reviews.append(review)

我确信跳过查找并添加id会更有效,但这可能吗?

3 个答案:

答案 0 :(得分:7)

您最好的选择可能是对支持表格撰写update表达式。否则,你无法在没有实际查询的情况下真正修改Review(这就是你正在做的事情;你实际上根本没有修改Artist。)

假设Review.id是主键,那大致是:

conn = session.connection()
conn.execute(Review.__table__
                .update()
                .values(artist_id=artist_id)
                .where(Review.id.in_(review_ids))
            )

答案 1 :(得分:6)

我认为如果你想坚持纯粹的ORM解决方案,你将不得不忍受一些效率低下的查询模式。

@TokenMacGuy提供了一个很好的选择。您可以通过将add_reviews()添加到Artist()类来集成该方法。这会增加'标准'orm api,所以你可以根据具体情况使用它。

from sqlalchemy.orm.session import object_session

class Artist(Base):
    def add_reviews(self, review_ids):
        sess = object_session(self)
        if isinstance(review_ids, int): review_ids = [review_ids]
        sess.execute(
            Review.__table__
            .update()
            .values(artist_id=self.artist_id)
            .where(Review.id.in_(review_ids))
        )
        sess.refresh(self)

review_ids = [123, 556, 998, 667, 111]
artist.add_reviews(review_ids)
review_id = 333
artist.add_reviews(review_id)

答案 2 :(得分:2)

我不确定我是否理解。我想你想要这样的东西:

reviews = session.query(Review).filter(Review.id.in_(review_ids)).all()

artist.reviews.extend(reviews)