【问题标题】:SQLAlchemy - Cannot evaluate BinaryExpression with operatorSQLAlchemy - 无法使用运算符评估 BinaryExpression
【发布时间】:2018-12-15 17:30:06
【问题描述】:

我正在尝试使用以下代码更新表中的一些记录:

session.query(Post).filter(
    Post.title.ilike("%Regular%")
).update({"status": False})

但问题是代码抛出如下异常:

InvalidRequestError: Could not evaluate current criteria in Python: "Cannot evaluate BinaryExpression with operator <function ilike_op at 0x7fbb88450ea0>". Specify 'fetch' or False for the synchronize_session parameter.

但是,如果我将synchronize_session=False 传递给update(),它会奇迹般地工作。

session.query(Post).filter(
    Post.title.ilike("%Regular%")
).update({"status": False}, synchronize_session=False)

那么synchronize_session有什么用呢?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    Query.update 是一个批量操作,即它在 Sqlalchemy 的工作单元事务模型之外运行。

    synchronize_session 提供了一种方法来指定更新是否应考虑会话中但不在数据库中的数据。

    来自docs

    同步会话 选择更新对象属性的策略 会议。有效值为:

    False - 不同步会话。一旦会话过期,此选项最有效且最可靠,这通常 发生在 commit() 之后,或显式使用 expire_all()。之前 过期,更新的对象可能仍保留在过期的会话中 他们的属性值,这可能会导致混乱的结果。

    因此,使用synchonize_session=False,数据库中更新的值不会在会话中更新。

    'fetch' - 在更新之前执行选择查询以查找与更新查询匹配的对象。更新的属性 在匹配的对象上过期。

    传递fetch 使sqlalchemy 识别受更新影响的会话中的值,并且当下次访问它们时,sqlalchemy 将查询数据库以获取它们的更新值

    'evaluate' - 直接在会话中的对象上评估 Python 中的查询条件。如果评估标准不 实施,引发异常。

    在您的代码中,您没有为synchronize_session 指定值,因此默认值evaluate 适用。 Sqlalchemy 在不委托给数据库的情况下找不到在模型上执行 ilike 的方法,因此它会引发异常以使开发人员决定是否将会话中的值与数据库中的值同步。

    【讨论】:

    • 我也从文档中读到过。但这没有多大意义。能详细点吗?
    • @Cody 我已经详细说明了。现在更有意义了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多