python - 使用 sqlalchemy 核心的 MySQL 多表更新查询?

标签 python mysql sqlalchemy

我想使用一个查询更新两个表。

我想要类似这样的东西

UPDATE tblReceipt, tblReturn
   SET tblReceipt.ReturnedDate = tblReturn.CreatedDate, 
       tblReturn.ReturnerName = tblReceipt.Name
 WHERE tblReturn.Id = tblReceipt.ReturnId
   AND tblReceipt.returned = TRUE

我目前有以下内容,但不确定如何添加第二个表引用。有没有简单的方法可以做到这一点?

    update(Receipt)
    .values(ReturnedDate=Return.CreatedDate, ReturnName=Receipt.Name) 
    .where(Return.Id==Receipt.ReturnId) 
    .where(Receipt.Returned == True)

最佳答案

来自 update() 的文档:

The keys within values can be either Column objects or their string identifiers (specifically the “key” of the Column, normally but not necessarily equivalent to its “name”). Normally, the Column objects used here are expected to be part of the target Table that is the table to be updated. However when using MySQL, a multiple-table UPDATE statement can refer to columns from any of the tables referred to in the WHERE clause.

强调我的。

我已经根据您上面的示例创建了一个示例核心模式,但并不准确,但应该足以处理:

from sqlalchemy_app import engine

import sqlalchemy as sa

metadata = sa.MetaData()

receipt = sa.Table(
    "receipt",
    metadata,
    sa.Column("id", sa.Integer, primary_key=True),
    sa.Column("something", sa.Integer),
)

returns = sa.Table(
    "returns",
    metadata,
    sa.Column("id", sa.Integer, primary_key=True),
    sa.Column("receipt_id", sa.Integer, sa.ForeignKey('receipt.id')),
    sa.Column("somethingelse", sa.Integer)
)


if __name__ == "__main__":
    metadata.drop_all(engine)
    metadata.create_all(engine)
    with engine.connect() as conn:
        conn.execute(
            receipt.insert(
                values=[{"id": 1, "something": 1}]
            )
        )
        conn.execute(
            returns.insert(
                values=[{"id": 1, "receipt_id": 1, "somethingelse": 99}]
            )
        )
        conn.execute(
            sa.update(receipt)
            .values({receipt.c.something: 3, returns.c.somethingelse: 4})
            .where(sa.and_(receipt.c.id == 1, returns.c.id == 1))
        )

根据文档,.values() 中引用的两列的父表在 .where() 子句中引用。

这是它生成的更新语句:

2019-08-17 11:27:39,573 INFO sqlalchemy.engine.base.Engine UPDATE receipt, returns SET returns.somethingelse=%(returns_somethingelse)s, receipt.something=%(something)s WHERE receipt.id = %(id_1)s AND returns.id = %(id_2)s
2019-08-17 11:27:39,582 INFO sqlalchemy.engine.base.Engine {'returns_somethingelse': 4, 'something': 3, 'id_1': 1, 'id_2': 1}

请注意,如果您只是打印查询以检查它,您将得到如下所示的内容:

UPDATE receipt SET somethingelse=:returns_somethingelse, something=:something FROM returns WHERE receipt.id = :id_1 AND returns.id = :id_2

...因为这是 mysql 特定的行为,您必须使用 mysql 方言编译它:

from sqlalchemy.dialects import mysql
print(statement.compile(dialect=mysql.dialect())

将打印:

UPDATE receipt, returns SET returns.somethingelse=%s, receipt.something=%s WHERE receipt.id = %s AND returns.id = %s

关于python - 使用 sqlalchemy 核心的 MySQL 多表更新查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57532513/

相关文章:

python - 如何在python中检查URL是否弹出

python - 为什么 `max` 和 `min` 在使用空可迭代对象调用时不返回适当的无穷大?

php - 在事务数据库上使用什么 mysql 扩展

python sqlAlchemy : got InvalidRequestError after change class location

python - 在查询中选择硬编码值的方法是什么?

python - 如何在 Django 模型上为相关字段生成索引?

python - 如何使用 HiddenField 强制转换 WTForms 中的整数数据?

mysql - 获取直方图的数据

php - db_insert 呕吐 "Invalid parameter number: parameter was not defined"

python - SQLALCHEMY:执行批量 SELECT 语句