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

发布于 2024-11-07 23:56:28 字数 577 浏览 2 评论 0原文

是否可以使用 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)

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

Is it possible to add to a SQLAlchemy relationship using ids rather than objects?

For example, consider two declarative SQLAlchemy classes, Review and Artist, with a relationship between them:

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

class Artist(Base):
    # etc.

With a list of review ids to add to an artist, I seem to need to look up the artist from the id, then add the artist object to the review, like this:

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

I'm sure it would be more efficient to skip the lookup and just add the ids, but is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

童话 2024-11-14 23:56:28

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

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

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

Your best bet is probably to compose an update expression against the backing tables. Otherwise, you can't really modify a Review without actually querying for it (and that's what your doing; you aren't actually modifying the Artist at all).

Assuming Review.id is the primary key, That would roughly be:

conn = session.connection()
conn.execute(Review.__table__
                .update()
                .values(artist_id=artist_id)
                .where(Review.id.in_(review_ids))
            )
情丝乱 2024-11-14 23:56:28

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

I think if you want to stick with the pure ORM solution, you'll have to live with the somewhat inefficient querying pattern.

@TokenMacGuy has provided a good alternative. You could integrate that approach by adding add_reviews() to the Artist() class. This would augment the 'standard' orm api, so you could use either depending on the situation.

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)
陌若浮生 2024-11-14 23:56:28

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

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

artist.reviews.extend(reviews)

I'm not sure if I understood. I guess you want something like this:

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

artist.reviews.extend(reviews)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文