【问题标题】:SqlAlchemy look-ahead caching?SqlAlchemy 超前缓存?
【发布时间】:2013-04-30 03:52:34
【问题描述】:

编辑:主要主题: 有没有办法强制 SqlAlchemy 尽可能地预先填充会话? 尽可能多地从数据库同步状态(此时不会有数据库更新)。 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 尽可能预填充会话。我希望如果我只是将原始数据加载到内存中,那么我要做的最多就是动态地追逐一些连接(几乎所有查询都非常简单)。

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

【问题讨论】:

  • 您的问题过于冗长,您的问题到底是什么?
  • 听起来您想将 SqlAlchemy 用作数据库而不是 ORM。
  • 我不能只查询表(或者实际上,这对我想要的有用吗?),它是我挂断的 ORM 位。我有很多我依赖的多态性和关系。
  • 我基本上是想找到一个快速的解决方法,直到我能够正确解决我的整体设计不佳的问题。

标签: python sqlalchemy


【解决方案1】:

这种问题不太可能在五分钟内解决,但对于多对一的“单例”获取,我经常使用一个简单的方法。假设您正在加载大量 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 配方。

【讨论】:

  • 有查询结果后是否需要实际尝试属性访问?如果我直接查询表,这些列值是否保存在内存中以用于 ORM 查询?
  • 当 Query 发出 SELECT 时,它总是发出它,并且总是获取所有行 - 然后大多数 DBAPI 最终会在这些行中获取所有列,即使它们没有被读取。然后,它将这些行与 Session 中已加载的对象进行匹配,并丢弃那些已经存在对象的行。因此,除非您像该示例中那样进行查询缓存,否则查询始终会发出 SQL,除非使用 query.get() 并且标识已经存在。
  • 我最初并没有提到我的部分声明是使用 Elixir 定义的(我正在迁移),也许这造成了我的一些问题。以您建议的形式执行查询肯定会有所帮助。
猜你喜欢
  • 2010-09-17
  • 2012-04-29
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 2022-01-27
  • 2014-09-11
相关资源
最近更新 更多