Python 截取SQLAlchemy中模型上的所有查询

Python 截取SQLAlchemy中模型上的所有查询,python,sqlalchemy,Python,Sqlalchemy,我需要截取与SQLAlchemy中的模型相关的所有查询,以便在执行任何查询方法(all(),one(),scalar()等)时对其进行检查 我考虑过以下方法: 1.子类化查询类 我可以子类化sqlalchemy.orm.Query并覆盖执行代码,基本上从以下内容开始 但是,我正在编写一个库,可以在其他SQLAlchemy应用程序中使用,因此声明性基础的创建(更不用说引擎和会话)超出了我的范围 也许我遗漏了什么,可以在不知道会话的情况下覆盖模型的查询类吗 2.使用before_execute Co

我需要截取与SQLAlchemy中的模型相关的所有查询,以便在执行任何查询方法(
all()
one()
scalar()
等)时对其进行检查

我考虑过以下方法:

1.子类化查询类 我可以子类化
sqlalchemy.orm.Query
并覆盖执行代码,基本上从以下内容开始

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

也许我遗漏了什么,可以在不知道会话的情况下覆盖模型的查询类吗

2.使用before_execute Core事件 我还想过与这件事挂钩

问题在于它与发动机相连(见上文)。此外,我需要修改会话中的对象,我得到的印象是,我无法从该事件中访问会话


我希望能够做到的是:

  • session.query(MyModel).filter\u by(foo=“bar”).all()
    被执行
  • 截取该查询并执行类似于将查询存储在同一数据库中的日志表中的操作(不是字面上的意思,而是一组基本上需要与此示例操作完全相同的功能的不同内容)
  • 让查询像正常一样执行
  • 我最后要做的是在查询时动态地将另一个数据存储中的项注入SQLAlchemy数据库。虽然这看起来很愚蠢——相信我,它可能没有听起来那么愚蠢(甚至更愚蠢)

    查询事件可能对您有用

    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\u descriptions
    ,查看您的模型是否被查询。

    @Kosch如问题中所述,我不认为根据特定的引擎或会话,我会有任何运气☹.@科什:是的,正如你所说:这一事件进入了引擎——正如我在问题中所解释的,我不能使用引擎。我的代码是一个库,它为使用它的应用程序定义了一个模型和这个拦截代码,该应用程序定义并创建了引擎。我可以通过某种方式将其传递到我的库中,但是我仍然无法访问事件侦听器中的绑定会话。好的,显然,我可以从绑定到传递的引擎的新sessionmaker派生会话…是的,就是这样!为什么我没有在文档中看到这个事件对我来说是一个谜。改进:我使用weakref.WeakSet()来访问\u查询,这样只缓存在这里但不再被SQLAlchemy引用的查询可以被垃圾收集。