【发布时间】:2016-08-06 16:05:58
【问题描述】:
我需要拦截所有与 SQLAlchemy 中的模型相关的查询,以便在任何查询方法(all()、one()、scalar() 等)所在的位置检查它执行。
我考虑过以下方法:
1。子类化查询类
我可以继承sqlalchemy.orm.Query 并覆盖执行代码,基本上从this 之类的东西开始。
但是,我正在编写一个可以在其他 SQLAlchemy 应用程序中使用的库,因此创建声明性基础(更不用说引擎和会话)超出了我的范围。
也许我错过了一些东西,并且可以在不知道会话的情况下覆盖我的模型的 Query 类?
2。使用 before_execute 核心事件
我也想过用before_execute 事件挂钩执行。
问题在于它与引擎绑定(见上文)。另外,我需要修改会话中的对象,我的印象是我无法从该事件中访问会话。
我想要做的是:
-
session.query(MyModel).filter_by(foo="bar").all()被执行。 - 拦截该查询并执行诸如将查询存储在同一数据库中的日志表中(不是字面意思,而是一组不同的东西,基本上需要与此示例操作完全相同的功能)
- 让查询正常执行。
我最终要做的是在查询时将另一个数据存储中的项目即时注入 SQLAlchemy 数据库。虽然这看起来很愚蠢 - 相信我,它可能没有听起来那么愚蠢(甚至更愚蠢);)。
【问题讨论】:
-
@Kosch 正如问题中所解释的那样,我认为我不会有任何运气取决于特定的引擎或会话☹。
-
@Kosch 是的,正如你所说:这个事件利用了 engine - 我不能使用它,正如我的问题中所解释的那样。我的代码是一个库,它为使用它的应用程序定义模型和此拦截代码,并且该应用程序定义创建引擎。我可以以某种方式将它传递给我的库,但是我仍然无法访问事件侦听器中的绑定会话。
-
好吧,很明显,我可以从绑定到传递引擎的新会话创建者那里派生会话……
标签: python sqlalchemy