docs say(在链接部分的末尾):
会话在数据库中插入新行后,所有新生成的标识符和数据库生成的默认值都可以立即在实例上使用,也可以通过首次访问加载来实现。
immediately
和load-on-first-access
之间的区别是什么? SQLAlchemy在完成INSERT
操作后是否知道新的标识符和默认值,所以即使没有重新加载它们也不可用?
答案 0 :(得分:1)
SQLAlchemy将INSERT .. RETURNING
用于支持其获取主键的数据库,或使用mysql_insert_id
等特殊功能来处理不适合的数据库。
对于默认值,它会尝试使用RETURNING
,但如果不支持,则必须使用其他SELECT
。
此外,在特定情况下可能无法使用RETURNING
(甚至在受支持的DB上)(例如,当INSERT
语句被批处理时,请参阅this mailing list post)。
最后,SQLAlchemy仅在INSERT
之后默认提取主键。因此,只有主键可用"立即"而未配置的默认列是"首先加载访问"。如果需要它来获取生成的值,请指定server_default=FetchedValue()
。 (如果数据库不支持RETURNING
并且您为列指定了FetchedValue
,我不确定它是否仍然使用立即SELECT
获取值,或者只是回退到"负载上先访问"。)
答案 1 :(得分:1)
: SQLAlchemy从数据库中获取插入的每个会话对象的主键,并将其分配给会话对象。会话对象需要立即使用主键,因为在提交事务快照之前,对象进入持久状态并被添加到Identity Map集合,该集合将其键入其主键。 [The SQLAlchemy Session - In Depth]
load-on-first-access:与对象关联的数据库生成的默认值可能永远不会在其会话中使用。因此,为了节省资源,需要lazy loaded。