【问题标题】:Attaching a pre-built query to a scoped_session in SQLAlchemy将预构建的查询附加到 SQLAlchemy 中的 scoped_session
【发布时间】:2017-09-26 21:36:14
【问题描述】:

我在尝试对 SQLAlchemy ORM 中的 scoped_session 执行预构建查询时收到一个奇怪的错误 AttributeError: 'scoped_session' object has no attribute '_autoflush'

我正在使用上下文管理器来生成 scoped_session,

@contextmanager
def connect(my_session_factory):
    session = scoped_session(my_session_factory)
    try:
        yield session
    except Exception as exception:
        session.rollback()
        raise exception
    finally:
        session.close()

然后像这样使用它:

from sqlalchemy.orm import Query

query = Query(my_model).offset(my_offset).limit(my_limit)
with connect(my_session_factory) as session:
    instances = query.with_session(session).all()
    return instances

然而,这引发了上述异常。

我还注意到session.query(my_model) 形式的查询工作正常。

我哪里错了?非常感谢!

【问题讨论】:

    标签: python session sqlalchemy


    【解决方案1】:

    好的 - 我对提出的问题没有答案,但我似乎有一个解决方法。

    问题似乎与scoped_session 对象的代理行为有关。据我了解,scoped_session() 方法采用sessionmaker 对象并使用它来创建线程本地session 对象。但是,scoped_session() 方法不会返回此线程本地 session。相反,它返回一个scoped_session 对象,该对象以某种方式(我不完全清楚)包含线程本地session。要直接访问此线程本地会话,您可以使用scoped_session.registry(),或者简单地使用scoped_session(),其中scoped_sessionscoped_session object,它已由scoped_session 方法返回.

    my_scoped_session = scoped_session(my_session_factory)
    my_local_session = my_scoped_session()
    

    现在问题来了:由于scoped_session 对象的代理行为,文档似乎表明my_scoped_session.query(...).all()my_local_session.query(...).all() 等调用是等效的。我发现这在很大程度上是正确的,但在我最初的问题案例中并非如此。

    如果您执行my_query = Query(...)(即构建非会话绑定查询),然后将其附加到scoped_session 对象(希望利用scoped_session 代理机制,以便处理my_queryscoped_session thread-local session) 的上下文中,通过my_instances = my_query.with_session(my_scoped_session).all() 或类似的方式,您可以在我原来的问题中得到回溯。

    我的解决方法是完全跳过scoped_session 对象的代理机制,而是将my_query 直接绑定到my_local_session

    my_query = Query(...).filter(...).sort(...)
    my_instances = my_query.with_session(my_local_session).all()
    

    这似乎行得通。但是,如果有人愿意指出直接使用scoped_session(my_session_factory)() 而不是使用scoped_session(my_session_factory)(大多数在线教程似乎都这样做)的危险(如果有的话?),那么我将不胜感激!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多