如何重用/克隆sqlalchemy查询

vir*_*tor 4 python caching sqlalchemy

在我看来,通过创建表达式树的整个过程,然后再次创建一个查询是使用sqlalchemy时浪费的时间.除了偶尔的动态查询之外,在应用程序的整个生命周期中几乎所有内容都是完全相同的(除了参数当然).

有没有办法在创建查询后保存查询并在以后使用不同的参数重新使用它?或者也许有一些内部机制已经做了类似的事情?

zzz*_*eek 19

在我看来,通过创建表达式树的整个过程,然后再次创建一个查询是使用sqlalchemy时浪费的时间.

与其他应用程序相比,您是否估计浪费了多少时间?在使程序更复杂之前,在此进行概要分析非常重要.我经常会注意到,Reddit每天提供超过10亿的页面浏览量,他们使用SQLAlchemy Core来查询他们的数据库,上次我查看他们的代码时他们没有尝试优化这个过程 - 他们构建了表达式树飞行和编译每次.但是,我们已经让用户确定他们的特定系统实际上受益于这些领域的优化.

我在这里写了一些关于分析的背景知识:我如何分析SQLAlchemy驱动的应用程序?

有没有办法在创建查询后保存查询并在以后使用不同的参数重新使用它?或者也许有一些内部机制已经做了类似的事情?

有几种方法,具体取决于您使用的API以及您希望优化的区域.

渲染SQL有两个主要部分 - 可以说是表达式树的构造,然后是表达式树中字符串的编译.

树本身,如果使用Core,可以是select()构造,如果使用ORM,可以是Query(),可以重复使用.select()特别没有任何与之关联的东西,阻止它像你喜欢的那样经常被重用(对于insert(),delete(),update()等都是如此).

在ORM中,查询也可以使用with_session()方法与不同的会话一起使用.这里的胜利并不多,因为每次调用它时Query()仍会产生一个整体select().但是正如我们将在下面看到的那样,有一个配方可以允许缓存它.

下一级优化涉及缓存实际呈现的SQL文本.这是一个需要更多关注的领域,因为我们生成的SQL特定于目标后端; 还有一些边缘情况,其中各种参数化改变了SQL本身(例如使用SQL Server的"TOP N ROWS",我们不能在那里使用绑定参数).使用execution_options()方法提供SQL字符串的缓存,该方法Connection也可以在其他一些地方使用,compiled_cache通过向其发送字典或其他类似字典的对象来设置该功能,该对象将缓存语句的字符串格式,键入到方言,构造的身份和发送的参数.ORM通常将此功能用于插入/更新/删除语句.

还有我已为配方它集成了compiled_cache与特征Query,在BakedQuery.通过接受任何Query说法query.bake(),您现在可以使用any运行该查询,Session只要您不在其上调用任何更多链接的方法,它应该每次使用SQL字符串的缓存形式:

q = s.query(Foo).filter(Foo.data==bindparam('foo')).bake()

for i in range(10):
    result = q.from_session(s).params(foo='data 12').all()
Run Code Online (Sandbox Code Playgroud)

它是实验性的,并不经常使用,但它正是你在这里所要求的.我建议你根据自己的需要定制它,在使用它时注意内存使用情况,并确保遵循它的工作原理.