是否可以使用几个不是主键的字段来从标识映射中检索项目(之前已经提取)?例如,我经常按(external_id, platform_id)
对查询表,这是一个唯一的键,但不是主键。在这种情况下,我希望省略不必要的SQL查询。
identity_map和get()的简要概述:
为SQLAlchemy的session
对象的生命周期保留身份映射,即在web服务或RESTful api的情况下,session
对象的生命期不超过一个request
(推荐)。
发件人:http://martinfowler.com/eaaCatalog/identityMap.html
"标识映射"保存已从中读取的所有对象的记录单个业务事务中的数据库。每当你想要一个物体时,你都要先检查身份图,看看你是否已经有了它
在SQLAlchemy的ORM中,有一种特殊的查询方法get()
,它首先使用pk(仅允许的参数)查看identity_map
,并从身份映射中返回对象,实际执行SQL
查询并访问数据库。
来自文档:
get(ident)
返回基于给定主键标识符或
None
的实例如果没有找到。
get()
的特殊之处在于它提供了对身份的直接访问拥有CCD_ 10的地图。如果给定的主键标识符是存在于本地标识映射中,则直接返回对象从该集合中,并且不会发出SQL,除非对象标记为完全过期。如果不存在,则按顺序执行SELECT以定位对象。
只有get()
在使用identity_map
-官方文档:
它在某种程度上被用作缓存,因为它实现了
identity map
模式,并存储键控到其primary key
的对象。然而不做任何类型的查询缓存。这意味着,如果你说session.query(Foo).filter_by(name='bar')
,即使Foo(name='bar')
就在那里,在身份映射中,会话不知道那它必须向数据库发出SQL,取回行,并且然后,当它看到行中的主键时,它可以查看本地标识映射,并查看对象是否已经存在它只有当你说query.get({some primary key})
不必发出查询。
p.S.如果您不使用pk
进行查询,那么您一开始就没有达到identity_map
。
很少有相关的SO问题,有助于澄清概念:
强制在身份映射外部执行sqlalchemy ORM get()
可以按顺序访问整个身份映射:
for obj in session.identity_map.values():
print(obj)
要通过任意属性获取对象,必须先筛选对象类型,然后检查属性。
它不是在恒定时间内进行查找,但可以防止不必要的查询。
有一个论点是,对象可能已被另一个进程修改,并且标识映射不保持当前状态,但这个论点是无效的:如果事务隔离级别为read committed
(或更低)-通常情况下,数据ALWAYS可能在查询完成后立即更改。