sqlalchemy - 如何使用 sqlalchemy 核心编写 UPDATE 左连接多表查询(MySQL)?
问题描述
如何用 sqlalchemy 内核编写以下 sql?
update t1 left join t2 on t1.event_date=t2.event_date set t1.sales=coalesce(t2.sales,0);
解决方案
在 Python 控制台中运行以下代码:
Python 3.8.2 (default, May 6 2020, 10:53:18)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlalchemy
>>> print(sqlalchemy.__version__)
1.3.19
>>> from sqlalchemy import update, func, table, column, types
>>> from sqlalchemy.dialects import mysql
>>> mysql_dialect = mysql.dialect()
>>> c1 = column("id", types.Integer)
>>> c2 = column("event_date", types.Date)
>>> c3 = column("sales", types.Integer)
>>> t1 = table("t1", c1, c2, c3)
>>> c1b = column("id", types.Integer)
>>> c2b = column("event_date", types.Date)
>>> c3b = column("sales", types.Integer)
>>> t2 = table("t2", c1b, c2b, c3b)
>>> j = t1.outerjoin(t2, t1.c.event_date == t2.c.event_date)
>>> v = {t1.c.sales: func.coalesce(t2.c.sales, 0)}
>>> s = update(j).values(v)
>>> print(s.compile(dialect=mysql_dialect))
UPDATE t1 LEFT OUTER JOIN t2 ON t1.event_date = t2.event_date SET sales=coalesce(t2.sales, 0)
你看,最终的结果非常接近完美的 SQL:只有语句t1.
中缺少前缀。SET sales=...
我认为这是 SQLAlchemy 1.3.19 的一个错误(或缺少功能)。所以我为此提交了一个问题:https ://github.com/sqlalchemy/sqlalchemy/issues/5617
它可能在某些情况下有效。但是对于您的情况,ERROR: Column 'sales' in field list is ambiguous
当 SQL 在实际的 MySQL 服务器上运行时会引发,因为列名存在于两个表中(这就是模棱两可的意思)。
于 2020-09-30 编辑:
zzzeek (Mike Bayer) 提出了一种解决方法:
>>> s = update(j).values(v).where(t1.c.id > 0)
>>> print(s.compile(dialect=mysql_dialect))
UPDATE t1 LEFT OUTER JOIN t2 ON t1.event_date = t2.event_date SET t1.sales=coalesce(t2.sales, 0) WHERE t1.id > 0
master
他还在分支和分支中提交了针对此问题的修复程序rel_1_3
。希望它会在 SQLAlchemy 的下一个 1.3.x 次要版本中尽快修复。
推荐阅读
- javascript - 如何使用 ListStyle.heroCard 将自定义数据添加到 ChoicePrompt
- python - 我如何让不和谐的机器人存储来自 DM 的消息,但只有在他们在服务器中完成命令后
- tensorflow - ImportError:DLL 加载失败,错误代码 3221225501 tensorflow
- python - 需要将单词月份转换为表格中的数字
- jspdf - didCellParse 不返回单元格
- sql - 使用 SQL 重新格式化多特征时间序列数据
- android - Android SortedList 拖动并重新排序项目抛出 IndexOutOfBoundsException:检测到不一致。无效的视图支架适配器 positionViewHolde
- css - 在 flexbox 中调整项目宽度时遇到异常麻烦
- spring-boot - Spring security requireSecure 重定向循环
- asp.net-core - 如何为 API 和 UI 设置不同的身份验证