2011-05-16 35 views
5

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

例如,考虑两个声明的SQLAlchemy类,审查和艺术家,与他们之间的关系:

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,但是这可能吗?

回答

6

您最好的选择可能是对组合的支持表的update表达。否则,如果没有实际查询Review,则无法真正修改Review(这就是您的所作所为;您实际上并未修改Artist)。

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

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

辉煌,谢谢。 – 2011-05-18 09:09:01

1

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

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

artist.reviews.extend(reviews) 
+0

其实这就是我正在做的!我编写了上面的代码来提供一个更简单的例子。它仍在为每个插入查找Review对象,我试图避免这种情况。尽管感谢您的建议。 – 2011-05-17 08:56:38

3

我认为,如果你想坚持纯粹的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)