SQLAlchemy不仅通过主键从身份映射中获取项目



是否可以使用几个不是主键的字段来从标识映射中检索项目(之前已经提取)?例如,我经常按(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可能在查询完成后立即更改。

最新更新