python - 使用字典列表更新 SQL 表
问题描述
如何在 SQL 查询中正确使用字典?我应该预定义 SQL 变量以防止 SQL 注入吗?例如,在尝试使用字典更新表时,我在 Python 中遇到了错误,但查询在具有预定义变量和值的纯 SQL 中完美运行。
_mysql_connector.MySQLInterfaceError: Incorrect datetime value: '1' for column 'colF' at row 1
我的听写
{'ID': 1, 'colA': 'valA1', 'colB': 'valB1', 'colC': 'valC1',
'colD': 'valD1', 'colE': 'valE1', 'colF': datetime.datetime(2017, 12, 23, 0, 0),
'colG': datetime.datetime(2018,
7, 11, 0, 0), 'colH': datetime.datetime(2018, 9, 1, 0, 0)}
SQL 语句
UPDATE table1
SET
colA = CASE \
WHEN %(valA1)s IS NOT NULL THEN %(valA1)s
END,\
colB = CASE \
WHEN %(valB1)s IS NOT NULL THEN %(valB1)s
END,\
colC = CASE \
WHEN %(valC1)s IS NOT NULL THEN %(valC1)s
END,\
colD = CASE \
WHEN %(valD1)s IS NOT NULL THEN %(valD1)s
END,\
colE = CASE \
WHEN %(valE1)s IS NOT NULL THEN %(valE1)s
END,\
colF = CASE\
WHEN %(valF)s IS NOT NULL THEN %(valF)s
END,\
colG = CASE\
WHEN %(valF1)s IS NOT NULL THEN %(valF1)s
END,\
colH = CASE\
WHEN %(valH1)s IS NOT NULL THEN %(valH1)s
END\
WHERE %(ID)s = Id """
当我格式化查询字符串时
colF1 = CASE
WHEN 2018-07-11 00:00:00 IS NOT NULL THEN 2018-07-11 00:00:00
END,
colH1 = CASE
WHEN 2018-09-01 00:00:00 IS NOT NULL THEN 2018-09-01 00:00:00
END
WHERE Id = 1
还有一个问题when value is not null
。语法是错误的,我想。
解决方案
您尝试的参数化查询会出现几个问题:
如MySQLdb文档中所述,列或表标识符不能用于参数占位符。此类占位符仅用于文字值。此外,请考虑多行的三引号字符串以避免
\
换行:sql = """UPDATE table1 SET colA = CASE WHEN colA IS NOT NULL THEN %(valA1)s END, ... """ cur.execute(sql, mydict) con.commit()
要使用命名占位符方法,字典键必须匹配占位符名称。目前,您需要反转字典中的大部分键/值顺序,而您正确地只为
ID
. 但是,如上面 #1 中所述,删除所有列标识符:{'ID': 1, 'valA1': 'data value', 'valB1': 'data value', 'valC1': 'data value', ... }
包括 MySQL 在内的大多数数据库中的日期时间必须采用字符串形式
YYYY-MM-DD HH:MM:SS
。MySQL 引擎无法执行 Python 的datetime()
对象。但是,某些 DBI-API 可能能够转换此对象类型。{'valF': '2017-12-23 00:00:00', 'valG': '2018-07-11 00:00:00', 'valH': '2018-09-01 00:00:00'}
推荐阅读
- javascript - Firebase signInWithEmailAndPassword 在 UI 焦点更改之前不会触发 .then()
- c++ - 阅读格式不一致的文本文件
- html - 如何通过 .exe 接受除 .exe 之外的所有文件类型控制
- google-ads-api - 通过 Google Ads API 运行或安排 Adwords 脚本
- c# - 在 c# 中使用 wordpay 创建桌面应用程序自助服务亭
- html - Outlook CSS 渲染与浏览器不同
- zurb-foundation - 将样式应用于 Zurb 电子邮件基础中的列
- reactjs - 如何在 createMuiTheme 中使用断点?材质 UI 和 React.js
- jquery - 革命滑块 - 如果滑块全高,则停止滚动页面
- c# - 确定多边形背面的算法