MariaDB executemany 在 Debian Stretch 中的重复键上
MariaDB executemany on duplicate key in Debian Stretch
谁能给我解释一下这是错误还是功能?
- Debian 扩展
- mariadb-server-10.1.26
- mariadb-client-10.1.26
- MySQLdb-1.2.5
此 python 代码在 Debian Jessie 中完美运行,但在 Stretch 中失败并出现错误:
Traceback (most recent call last):
File "bug_check.py", line 17, in <module>
cur.executemany(q, p)
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 255, in executemany
self.errorhandler(self, TypeError, msg)
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
TypeError: not all arguments converted during string formatting
Python代码:
#!/usr/bin/python
# -*- coding: UTF-8 *
import MySQLdb
db = MySQLdb.connect(host='192.168.1.183', user='root', passwd='password', db='test', charset='utf8')
cur = db.cursor()
q = """INSERT INTO test2 (id, value)
VALUES (%s, %s)
ON DUPLICATE KEY
UPDATE value=%s
"""
p = [(1, 7, 7)]
# failed
cur.executemany(q, p)
# working
for i in p:
cur.execute(q, i)
db.commit()
db.close()
数据库:
CREATE TABLE `test2` (
`id` bigint(8) NOT NULL,
`value` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `test2`
ADD PRIMARY KEY (`id`);
ALTER TABLE `test2`
MODIFY `id` bigint(8) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
我正在尝试 mariadb-10.2、pymysql,但无论如何在 Stretch 中出现错误。
这 可能 工作:将 UPDATE value=%s
更改为 UPDATE value=VALUES(value)
并删除数组中的最后一个 7
。
如果这不起作用,那么这里有更多的讨论:
我认为 executemany
正在尝试构建
INSERT ...
VALUES (...),
(...),
(...);
但它不知道如何将IODKU 语法转换成这样的重复列表。底线:您可能可以将 executemany
与 INSERT
、INSERT IGNORE
、REPLACE
一起使用,但不能使用 IODKU。
为了使 IODKU 正常工作,Stretch 需要足够聪明才能做到这一点:
INSERT INTO test2 (id, value)
VALUES
(%s, %s),
(%s, %s),
(%s, %s),
(%s, %s),
etc
ON DUPLICATE KEY
UPDATE value=VALUES(value)
请注意,重复是在中间,而不是在其他情况下的末尾。但是 you 必须使用 VALUES()
伪函数来避免 UPDATE
子句中的 %s
。
谁能给我解释一下这是错误还是功能?
- Debian 扩展
- mariadb-server-10.1.26
- mariadb-client-10.1.26
- MySQLdb-1.2.5
此 python 代码在 Debian Jessie 中完美运行,但在 Stretch 中失败并出现错误:
Traceback (most recent call last):
File "bug_check.py", line 17, in <module>
cur.executemany(q, p)
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 255, in executemany
self.errorhandler(self, TypeError, msg)
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
TypeError: not all arguments converted during string formatting
Python代码:
#!/usr/bin/python
# -*- coding: UTF-8 *
import MySQLdb
db = MySQLdb.connect(host='192.168.1.183', user='root', passwd='password', db='test', charset='utf8')
cur = db.cursor()
q = """INSERT INTO test2 (id, value)
VALUES (%s, %s)
ON DUPLICATE KEY
UPDATE value=%s
"""
p = [(1, 7, 7)]
# failed
cur.executemany(q, p)
# working
for i in p:
cur.execute(q, i)
db.commit()
db.close()
数据库:
CREATE TABLE `test2` (
`id` bigint(8) NOT NULL,
`value` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `test2`
ADD PRIMARY KEY (`id`);
ALTER TABLE `test2`
MODIFY `id` bigint(8) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
我正在尝试 mariadb-10.2、pymysql,但无论如何在 Stretch 中出现错误。
这 可能 工作:将 UPDATE value=%s
更改为 UPDATE value=VALUES(value)
并删除数组中的最后一个 7
。
如果这不起作用,那么这里有更多的讨论:
我认为 executemany
正在尝试构建
INSERT ...
VALUES (...),
(...),
(...);
但它不知道如何将IODKU 语法转换成这样的重复列表。底线:您可能可以将 executemany
与 INSERT
、INSERT IGNORE
、REPLACE
一起使用,但不能使用 IODKU。
为了使 IODKU 正常工作,Stretch 需要足够聪明才能做到这一点:
INSERT INTO test2 (id, value)
VALUES
(%s, %s),
(%s, %s),
(%s, %s),
(%s, %s),
etc
ON DUPLICATE KEY
UPDATE value=VALUES(value)
请注意,重复是在中间,而不是在其他情况下的末尾。但是 you 必须使用 VALUES()
伪函数来避免 UPDATE
子句中的 %s
。