Python 中使用不定长字典构造 sql 语句问题

2020-03-27 16:40:30 +08:00
 j0shfan

现在有一个需要 在程序中使用不定长的字典构造 sql 语句 Insert INTO (字典的键) VALUE (字典的值) 由于使用于 mysql,因为安全原因,不想使用+法来构造 其他三种 python 字符串构造方法好像都不行, a.使用% b.使用 format() c.使用 f-string 我没想出来方案,请大神指点迷津

2621 次点击
所在节点    Python
17 条回复
todd7zhang
2020-03-27 17:15:10 +08:00
d = {'name': 123, 'age': 456}
keys = d.keys()
sql = 'insert into (%s) value (%s)' % (','.join('%s' % k for k in keys), ','.join('%%s' for _ in keys))
cr.execute(sql, tuple(d.values()))
todd7zhang
2020-03-27 17:15:56 +08:00
后面是 %s for_ in keys
关键是 构造出 'insert into (name, age) values (%s, %s)' 就行了
Vegetable
2020-03-27 17:26:11 +08:00
我寻思这加号和直接字符串方法在安全上有区别吗?不都是直接拼接 SQL 吗?
wuwukai007
2020-03-27 17:26:38 +08:00
没看懂+怎么会不安全,用了多线程吗
sikong31
2020-03-27 17:26:40 +08:00
def insert(self, table, **kw):
fields, values = zip(*kw.items())
fields_str = ','.join(fields)
values_str = ','.join(['?'] * len(fields))
sql = f"INSERT INTO {table} ({fields_str}) values ({values_str})"
self.con.execute(sql, values)
wysnylc
2020-03-27 17:27:40 +08:00
注入警告
xpresslink
2020-03-27 17:32:26 +08:00
>>> d = {'name': 123, 'age': 456}
>>> 'insert into table{0} values{1};'.format(tuple(d.keys()),tuple(d.values()))
"insert into table('name', 'age') values(123, 456);"
>>>
xpresslink
2020-03-27 17:37:44 +08:00
但是不建议一条一条的插入,最好用批量插入,数据量大了效率差万倍。
建一个插入模板
>> sql = 'insert into (name, age) values (%s, %s)'
>> conn.executemany(sql, list(d.values()))
大多数 python 的 mysql 驱动接口都带 executemany()方法。
sikong31
2020-03-27 17:39:11 +08:00
@xpresslink 他这是不定长的字典,键多少不固定,批量不了
ClericPy
2020-03-27 18:05:44 +08:00
防注入就用框架吧... 我现在用的 databases, 貌似是基于 aiomysql 和 sqlalchemy 的, 直接丢字典进去就行了...
fzhyzamt
2020-03-27 18:21:53 +08:00
mysql 那几个库好像自带防注入的,只要你不把数据直接 format 到语句里,所以你提的那三种方式没啥区别
j0shfan
2020-03-27 19:14:24 +08:00
@todd7zhang 这样可行,感谢方案
j0shfan
2020-03-27 19:15:57 +08:00
@xpresslink 可以,简洁明了
j0shfan
2020-03-27 19:19:10 +08:00
@sikong31 方案可以,感谢
j0shfan
2020-03-27 19:25:39 +08:00
@xpresslink 感谢提醒
Trim21
2020-03-27 19:30:40 +08:00
j0shfan
2020-03-27 19:48:05 +08:00
@Trim21 我用了 mysql python 官方连接器,有空我了解下 SQLAlchemy,多谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/656843

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX