Skip to main content
 首页 » 编程设计

python之SqlAlchemy 超前缓存

2025年05月04日8Leo_wl

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

我遇到了一些轻微的性能问题,我相信我已经将其追溯到 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 尽可能预填充 session 。我希望如果我只是将原始数据加载到内存中,那么我要做的最多就是动态地追踪一些连接(几乎所有查询都非常简单)。

我希望有 5 分钟的修复时间,这样我就可以尽快生成一些报告。我下个月的 TODO 可能会充满直接的表查询和可以流水线化元组的更严格的业务逻辑。

请您参考如下方法:

不太可能在五分钟内解决此类问题,但对于多对一“单例”获取,有一个我经常使用的简单方法。假设您正在加载大量 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 语句的结果,缓存仅与当前 session - 查看 local_session_caching.py分发示例中包含的配方。