在SQLAlchemy中拦截模型上的所有查询

时间:2016-08-06 16:05:58

标签: python sqlalchemy

我需要拦截与SQLAlchemy中的模型有关的所有查询,我可以在任何查询方法(all()one(),{{1}的位置检查它执行。

我考虑过以下方法:

1。查询类

的子类

我可以继承scalar()并覆盖执行代码,基本上从this开始。

但是,我正在编写一个可以在其他SQLAlchemy应用程序中使用的库,因此创建声明性基础,更不用说引擎和会话,超出了我的范围。

也许我错过了一些东西,可以在不知道会话的情况下覆盖我的模型的Query类?

2。使用before_execute核心事件

我还想过用before_execute事件挂钩执行。

问题是它被绑定到引擎(见上文)。此外,我需要修改会话中的对象,并且我得到的印象是我无法访问此事件中的会话。

我希望能够做的是:

  1. sqlalchemy.orm.Query已执行。
  2. 拦截该查询并执行类似的操作,例如将查询存储在同一数据库中的日志表中(不是字面意思,而是一组基本上需要与此示例操作完全相同的功能的不同内容)
  3. 让查询执行正常。
  4. 我最终要做的是在查询时将其他数据存储中的项目即时注入SQLAlchemy数据库。虽然这看起来很愚蠢 - 相信我,它可能不像听起来那么愚蠢(甚至更愚蠢);)。

1 个答案:

答案 0 :(得分:2)

before_compile查询事件可能对您有用。

from weakref import WeakSet
from sqlalchemy import event
from sqlalchemy.orm import Query

visited_queries = WeakSet()

@event.listens_for(Query, 'before_compile')
def log_query(query):
    # You can get the session
    session = query.session

    # Prevent recursion if you want to compile the query to log it!
    if query not in visited_queries:
        visited_queries.add(query)
        # do something with query.statement

您可以查看query.column_descriptions以查看您的模型是否正在被查询。