2

编辑:主题: 有没有办法可以强制 SqlAlchemy 尽可能预填充会话?从数据库中同步尽可能多的状态(此时不会有数据库更新)。

我遇到了一些轻微的性能问题,我相信我已经将其追溯到 SqlAlchemy。我确信我的声明性和 db-schema 有一些变化可以缩短时间,但这不是我在这里要问的。

我的 SqlAlchemy 声明性定义了 8 个类,我的数据库有 11 个表,其中只有 7 个保存我的真实数据,我的数据库总共有 800 条记录(所有整数和 UnicodeText)。我的数据库引擎是 sqlite,实际大小目前是 242Kb。

确实,实体的数量很少,但许多表关系具有递归行为(5-6 级深)。我的问题始于 SA 为我做的美妙的自动魔术,以及我不愿意用我自己的 python 类正确提取数据。

我的 ORM 属性访问分散在各种迭代器、递归评估器中,一直到我的文件 I/O 流。对这些属性的访问很大程度上是非线性的,每次我进行查找时,我的调用堆栈都会消失在 SqlAlchemy 中很长一段时间,并且我会收到很多单例查询。

我主要使用默认 SA 设置(python 2.7.2,sqlalchemy 0.7)。

考虑到 RAM 不是问题,而且我的数据库非常小(暂时),有没有一种方法可以强制 SqlAlchemy 尽可能地预先填充会话。我希望如果我只是将原始数据加载到内存中,那么我要做的最多就是动态地追逐一些连接(几乎所有查询都非常简单)。

我希望有一个 5 分钟的修复,以便我可以尽快运行一些报告。我下个月的 TODO 可能会充满直接的表查询和更紧密的业务逻辑,可以管道元组。

4

1 回答 1

1

此类问题的五分钟修复是不可能的,但对于多对一的“单例”获取,我经常使用一个简单的方法。假设您正在加载大量对象,并且它们都具有对某种a 的User多对一引用:Category

# load all categories, then hold onto them
categories = Session.query(Category).all()

for user in Session.query(User):
    print user, user.category  # no SQL will be emitted for the Category

这是因为query.get()多对一发出的 将首先在本地身份映射中查找主键。

如果您正在寻找更多的缓存(并且有超过五分钟的空闲时间),可以扩展相同的概念以缓存 SELECT 语句的结果,缓存仅与当前会话相关联- 查看分发示例中包含 的local_session_caching.py配方。

于 2013-04-29T19:52:34.207 回答