【问题标题】:How to write UPDATE FROM without a subquery in SQLAlchemy for PostgreSQL如何在 SQLAlchemy for PostgreSQL 中编写没有子查询的 UPDATE FROM
【发布时间】:2021-02-23 11:54:04
【问题描述】:

我正在编写一个查询,该查询通过计算其值与另一个表中的列之间的差异来更新表列。在原始 SQL 中,它如下所示:

UPDATE
    products
SET
    quantity = products.quantity - order_items.quantity
FROM
    order_items
WHERE
    order_items.order_id = %(order_id_1) s
    AND products.code = order_items.product_code;

我检查了 SQLAlchemy 文档,发现了一个关于 update 表达式的 section

WHERE 子句可以引用多个表。对于支持这一点的数据库,将生成一个 UPDATE FROM 子句,或者在 MySQL 上,一个多表更新。该语句将在不支持多表更新语句的数据库上失败。

我尝试按照文档所述实现查询:

query = (
        products_table.update()
        .values(quantity=products_table.c.quantity - order_items_table.c.quantity)
        .where(
            products_table.c.code
            == select([order_items_table.c.product_code])
            .where(
                and_(
                    order_items_table.c.order_id == order_id,
                    order_items_table.c.product_code == products_table.c.code,
                )
            )
            .as_scalar()
        )
    )

但我得到的不是简洁的UPDATE ... SET ... FROM 表达式:

from sqlalchemy.dialects import postgresql
str(query.compile(dialect=postgresql.dialect()))
UPDATE
    products
SET
    quantity =(products.quantity - order_items.quantity)
WHERE
    products.code = (
        SELECT
            order_items.product_code
        FROM
            order_items
        WHERE
            order_items.order_id = %(order_id_1) s
            AND order_items.product_code = products.code
    )

此外,此 SQL 查询并不完全正确,并且没有所需的FROM 语句。

因此,我试图弄清楚我的查询表达式有什么问题,以及是否有可能在没有子查询的情况下在 SQLAlchemy 中实现原始 SQL 的等效项。有什么想法吗?

版本

  • 操作系统:MacOS
  • Python:3.8.x
  • SQLAlchemy:1.3.20
  • 数据库:PostgreSQL 11.x

提前致谢!

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    看来我误读了文档。我发布的链接解释了相反的情况,并提供了为不支持 UPDATE FROM 的数据库编写查询的示例。

    我刚刚编写了以下查询:

    query = (
        products_table.update()
        .values(quantity=products_table.c.quantity - order_items_table.c.quantity)
        .where(products_table.c.code == order_items_table.c.product_code)
        .where(order_items_table.c.order_id == order_id)
    )
    

    它会生成正确的 SQL:

    UPDATE
        products
    SET
        quantity =(products.quantity - order_items.quantity)
    FROM
        order_items
    WHERE
        products.code = order_items.product_code
        AND order_items.order_id = %(order_id_1) s
    

    【讨论】:

      猜你喜欢
      • 2013-08-16
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 2017-12-29
      • 1970-01-01
      • 2011-10-30
      相关资源
      最近更新 更多