Mysql 在添加重复项时执行很多操作都不起作用

问题描述 投票:0回答:1

我有 mysql 表,我想为该表运行

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
时无法匹配所有参数?

python mysql pymysql executemany
1个回答
0
投票

我认为问题在于您不能在

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.']

另请参阅此答案https://stackoverflow.com/a/52260250/494134

© www.soinside.com 2019 - 2024. All rights reserved.