注意:这是在SQLAlchemy 0.5.7中。看起来这是不可能的,因为“懒惰”不适用于一对一映射。如果确实如此,我说错了,请发表您的回答。
我有以下方法,它应该返回父类为Parent
的任何类的所有实例。请注意,类Child
具有名为fubar
的属性,这是另一个类。我已经在其他地方正确地映射了这些。
def get_all(self):
session = self.__Session()
lst = session.query(Parent).with_polymorphic('*').all()
#print lst # <-- this commented back in and it all works.
session.expunge_all()
session.close()
return lst
然后我可以做for item in get_all(): [...]
之类的事情。在child
的映射中,我有lazy-False
所以我会假设它会被正确加载。但是,如果我将打印行留下来,我得到的只是这个例外:
UnboundExecutionError: Parent instance <Child at 0xa1bca4c> is not bound to a Session; lazy load operation of attribute 'fubar' cannot proceed
我不明白的是:当打印线在那里时,对象确实装好了。
我做错了什么?
编辑:感谢@van,我认为fubar
对象确实是以懒惰的方式加载的。我在映射中有以下内容:
sqlalchemy.orm.mapper(Child, tb_child, inherits=Parent,
polymorphic_identity='Child', properties={'fubar':
sqlalchemy.orm.relation(Child,
lazy=False,
uselist=False,
cascade="all, delete-orphan")
}
)
父母的代码是:
sqlalchemy.orm.mapper(Parent,
tb_parent,
polymorphic_on=tb_parent.c.type,
polymorphic_identity='Parent')
这有什么问题?...
或者,如何强制query()
以非懒惰的方式加载所有内容?
答案 0 :(得分:2)
从Relationship API documentation(向下滚动到lazy
参数的说明):
lazy=’select’ – specifies how the related items should be loaded. Default value is select. Values include:
...
noload - no loading should occur at any time. This is to support “write-only” attributes, or attributes which are populated in some manner specific to the application.
...
True - a synonym for ‘select’
False - a synonyn for ‘joined’
None - a synonym for ‘noload’
因此,通过设置lazy=None
,您实际上并没有将关系配置为急切加载,而是获得几乎相反的结果。您应该使用以下其中一个:immediate, joined or subquery
。
edit-1 :鉴于使用了SA-0.5这一事实:我不确定为什么关系不会急切加载,但您可能会尝试在查询中明确指定它看看它是否有效:
lst = (session.query(Parent).with_polymorphic('*').
options(eagerload('fubar')).all()) # confused if it is "fubar" or "ref"