executemany
。我想确保,如果有重复的条目,那么应该更新它。我用数据编写了如下查询。
a = 'INSERT INTO tabl (switch_id, readiness, message) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE readiness=%s, message=%s'
b = [(12780, 'not_ready', 'StatusDB data', 'not_ready', 'StatusDB data.'),
(12781, 'not_ready', 'StatusDB data.', 'not_ready', 'StatusDB data.')]
当我尝试使用数据库连接对象的
CONN
对这些数据执行许多操作时,会出现错误。
>>> with CONN.cursor() as c:
... c.executemany(a, [b[0]])
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 69, in executemany
return self._execute_with_wrappers(sql, param_list, many=True, executor=self._executemany)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _executemany
return self.cursor.executemany(sql, param_list)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 83, in executemany
return self.cursor.executemany(query, args)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 182, in executemany
return self._do_execute_many(
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 205, in _do_execute_many
v = values % escape(next(args), conn)
TypeError: not all arguments converted during string formatting
当我删除
ON DUPLICATE
语法时,它工作正常。
>>> with CONN.cursor() as c:
... c.executemany(a[:-49], [b[0][:3]])
...
Traceback (most recent call last):
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _executemany
return self.cursor.executemany(sql, param_list)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 83, in executemany
return self.cursor.executemany(query, args)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 182, in executemany
return self._do_execute_many(
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 220, in _do_execute_many
rows += self.execute(sql + postfix)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 153, in execute
result = self._query(query)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 322, in _query
conn.query(q)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 558, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 822, in _read_query_result
result.read()
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 1200, in read
first_packet = self.connection._read_packet()
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 772, in _read_packet
packet.raise_for_error()
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/protocol.py", line 221, in raise_for_error
err.raise_mysql_exception(self._data)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
raise errorclass(errno, errval)
pymysql.err.IntegrityError: (1062, "Duplicate entry '12780' for key 'tabl.PRIMARY'")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<console>", line 2, in <module>
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 69, in executemany
return self._execute_with_wrappers(sql, param_list, many=True, executor=self._executemany)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _executemany
return self.cursor.executemany(sql, param_list)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _executemany
return self.cursor.executemany(sql, param_list)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 83, in executemany
return self.cursor.executemany(query, args)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 182, in executemany
return self._do_execute_many(
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 220, in _do_execute_many
rows += self.execute(sql + postfix)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 153, in execute
result = self._query(query)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/cursors.py", line 322, in _query
conn.query(q)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 558, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 822, in _read_query_result
result.read()
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 1200, in read
first_packet = self.connection._read_packet()
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/connections.py", line 772, in _read_packet
packet.raise_for_error()
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/protocol.py", line 221, in raise_for_error
err.raise_mysql_exception(self._data)
File "/home/myuser/var/virtualenvs/venv//lib/python3.8/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
raise errorclass(errno, errval)
django.db.utils.IntegrityError: (1062, "Duplicate entry '12780' for key 'tabl.PRIMARY'")
它给出了 DUPLICATE 错误,但最终它能够到达数据库。而当我们使用原始查询时,它会给出参数错误。
如果我循环遍历参数并运行
cursor.execute
,它可以与 ON DUPLICATE
语法一起正常工作。
为什么我们使用
executemany
时无法匹配所有参数?
我认为问题在于您不能在
ON DUPLICATE KEY UPDATE
部分使用文字字符串值。您必须引用已在 VALUES
子句中给出的列值。
试试这个:
a = 'INSERT INTO tabl (switch_id, readiness, message) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE readiness=VALUES(readiness), message=VALUES(message)'
b = [(12780, 'not_ready', 'StatusDB data'),
(12781, 'not_ready', 'StatusDB data.']