确定sqlalchemy对象的实际加载/卸载状态及其关系

时间:2011-06-15 11:04:32

标签: python sqlalchemy

就我而言,对底层数据库的查询非常昂贵,所以我们尽可能地尝试保存数据库请求。

这是我将用于示例的简化数据库:

items_table = Table("invtypes", gdata_meta,
                    Column("typeID", Integer, primary_key = True),
                    Column("typeName", String, index=True),
                    Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))

mapper(Item, items_table,
       properties = {"group" : relation(Group, backref = "items"),
                     "ID" : synonym("typeID"),
                     "name" : synonym("typeName")})

groups_table = Table("invgroups", dbmetadata,
                     Column("groupID", Integer, primary_key = True),
                     Column("groupName", String))

mapper(Group, groups_table,
       properties = {"ID" : synonym("groupID"),
                     "name" : synonym("groupName")})

然后我们获取一些Item对象和其中一个组:

engine = create_engine("sqlite:///<path-to-db>", echo=True)
Session = sessionmaker(bind=engine)
session = Session()

itm = session.query(Item).get(11184)   #1
grp = session.query(Group).get(831)    #2

在这种特殊情况下,itm.groupID = 831,因此itm的组已经加载到内存中。但是:

>>>attributes.instance_state(itm).unloaded
set(['group', 'name', 'ID'])

SQLAlchemy表示卸载'itm'的'group'属性/关系。但是,在这种情况下,访问它时,不会向底层数据库发出任何查询,因为它已经在标记为#2的行中加载。第一次访问后,它不再标记为已卸载。

现在让我们完成上面的例子并进行一般性的讨论。访问Item对象的group属性时,可以在某处(即已在当前会话中映射)引用具有请求ID的组,或者仅存在于基础数据库中。

我目前的目标是找到一种方法可靠地确定具有给定ID及其'group'属性/关系的Item是否已经加载到内存中或执行itm加载,然后itm.group acccess,以及SQLAlchemy是否无法提取某些内容它的对象映射,即将向底层数据库发出查询 - 拦截它并发出另一个数据库请求。这应该保证它最多只需要一个数据库请求(必要时需要加载)以加载我需要的所有内容,或者如果所有内容都已加载则为零请求。

正如我在上面的一段中所描述的,attributes.instance_state()。unloaded不是一种可靠的方法。它不会检测从未访问过的属性/关系的实际加载状态。

我打算用它来优化涉及预先加载的查询(即,在所有请求的对象都已加载的情况下,这种情况经常在我的情况下发生,并且当这些查询不同时,查询缓存不起作用)他们)。

0 个答案:

没有答案