【问题标题】:SQLAlchemy: add a relationship using id instead of object?SQLAlchemy:使用 id 而不是对象添加关系?
【发布时间】:2011-08-26 20:06:04
【问题描述】:

是否可以使用 id 而不是对象添加到 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 会更有效,但这可能吗?

【问题讨论】:

  • 我可以通过关注 this answer 来完成此操作。

标签: python orm sqlalchemy relationship


【解决方案1】:

您最好的选择可能是针对支持表编写一个update 表达式。否则,您无法真正修改 Review 而不实际查询它(这就是您所做的;您实际上根本没有修改 Artist)。

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

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

【讨论】:

    【解决方案2】:

    我认为,如果您想坚持使用纯 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)
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 其实我就是这么做的!我编写上面的代码是为了提供一个更简单的示例。它仍在为每个插入查找 Review 对象,这是我试图避免的。不过谢谢你的建议。
      猜你喜欢
      • 2014-03-07
      • 1970-01-01
      • 2013-01-18
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 2014-06-12
      • 2014-05-19
      相关资源
      最近更新 更多