<p>要强制加载lazy属性,只需访问它们。这是最简单的方法,它对关系很好,但是对于<code>Column</code>s(您将为同一表中的每一列获得单独的SQL查询)效率低下。您可以从<code>sqlalchemy.orm.attributes.instance_state(obj).unloaded</code>获取所有已卸载属性(关系和列)的列表。在</p>
<p>示例中没有使用延迟列,但为了完整起见,我将在这里描述它们。处理延迟列的典型方案如下:</p>
<ul>
<li>用<code>deferred()</code>装饰选定的列。通过使用<code>group</code>参数将它们组合成一个或多个组。在</li>
<li>如果需要,请在查询中使用<code>undefer()</code>和<code>undefer_group()</code>选项。在</li>
<li>访问延迟列放入组将加载此组中的所有列。在</li>
</ul>
<p>不幸的是,这并不起相反的作用:您可以将列组合成组,而不必使用<code>column_property(Column(…), group=…)</code>来延迟加载它们,但是<code>defer()</code>选项不会影响它们(它只适用于<code>Column</code>s,而不是列属性,至少在0.6.7中是这样)。在</p>
<p>要强制加载延迟列属性,<code>session.refresh(obj, attribute_names=…)</code>由nathanvilaescusa建议的可能是最好的解决方案。我看到的唯一缺点是它首先使属性过期,因此必须确保作为<code>attribute_names</code>参数传递的属性中没有加载的属性(例如,使用与<code>state.unloaded</code>的交集)。在</p>
<p><strong>更新</strong></p>
<p>1)SQLAlchemy会跟踪加载的对象。ORM就是这样工作的:对于每个标识,会话中必须只有一个对象。默认情况下,它的内部缓存是弱的(使用<code>weak_identity_map=False</code>来更改它),因此只要代码中没有对该对象的引用,就会从缓存中删除该对象。当对象已经在会话中时,SQLAlchemy不会对<code>query.get(pk)</code>执行SQL请求。但这只适用于<code>get()</code>方法,因此<code>query.filter_by(id=pk).first()</code>将在会话中使用加载的数据执行SQL请求和刷新对象。在</p>
<p>2)急切地加载关系将导致更少的请求,但并不总是更快。你必须检查你的数据库和数据。在</p>
<p>2.1)从数据库重取数据不会卸载通过关系绑定的对象。在</p>
<p>2.2)<code>item.group</code>是使用<code>query.get()</code>方法加载的,因此如果对象已经在会话中,则不会导致SQL请求。在</p>
<p>2.3)是的,视情况而定。在大多数情况下,最好是希望SQLAlchemy使用正确的策略:)。对于已经加载的关系,您可以检查相关对象的关系是否通过<code>state.unloaded</code>以递归方式加载到任何深度。但是,当关系尚未加载时,您无法知道相关对象及其关系是否已加载:即使关系尚未加载,相关对象也可能已在会话中(想象一下,您先请求项,加载其组,然后请求具有相同组的其他项)。对于您的特定示例,我认为递归地检查<code>state.unloaded</code>没有问题。在</p>