如何在SQLAlchemy中将joinedload / contains_eager用于启用查询的关系(lazy =“ dynamic”选项)
我有SQLAlchemy声明的以下模型类:
class User(Base):
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False, unique=True)
created_at = Colmn(DateTime, nullable=False, default=func.now())
class Post(Base):
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey(User.id), nullable=False)
user = relationship(User, backref=backref('posts', lazy='dynamic'))
title = Column(String, nullable=False)
body = Column(Text, nullable=False)
created_at = Colmn(DateTime, nullable=False, default=func.now())
正如我所引用的,这些模型具有一种关系,其backref名称posts
设置为启用查询(通过lazy='dynamic'
选项)。因为某些用户可能拥有大量的帖子,而大多数用户却没有。
使用这些模型,我尝试joinedload
了User.posts
,但是遇到了错误:
>>> users = session.query(User).options(joinedload(User.posts))[:30]
Traceback (most recent call last):
...
InvalidRequestError: 'User.posts' does not support object population - eager loading cannot be applied.
有什么办法可以解决这种情况?我都需要同时具备以下两个功能:
- 有时
User.posts
可以切成薄片,以避免急于增加沉重的用户撰写的大量帖子。 - 但是通常
User.posts
不应产生1 + N个查询。
-
问题在于
User
职位的属性是动态关系;它应该返回一个Query
对象。该属性无法知道或安全地进行通信,这一次,所有相关项均已加载。一个简单的解决方法是拥有两个属性,一个属性使用正常的延迟加载行为(您可以将其设置为在有意义的情况下对特定查询进行紧急加载),另一个属性始终返回动态关系。
class User(Base): id = Column(Integer, primary_key=True) name = Column(String, nullable=False, unique=True) created_at = Colmn(DateTime, nullable=False, default=func.now()) class Post(Base): id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey(User.id), nullable=False) user = relationship(User, backref=backref('posts')) title = Column(String, nullable=False) body = Column(Text, nullable=False) created_at = Colmn(DateTime, nullable=False, default=func.now()) User.post_query = relationship(Post, lazy="dynamic")