【发布时间】:2017-11-14 12:20:02
【问题描述】:
我有一个 MySQL 数据库,其中包含一个名为 commands 的表,其结构如下:
+-----------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| input | varchar(3000) | NO | | NULL | |
| inputhash | varchar(66) | YES | UNI | NULL | |
+-----------+---------------+------+-----+---------+----------------+
我正在尝试在其中插入行,但前提是 inputhash 字段尚不存在。我认为INSERT IGNORE 是这样做的方法,但我仍然收到警告。
例如,假设able已经包含
+----+---------+------------------------------------------------------------------+
| id | input | inputhash |
+----+---------+------------------------------------------------------------------+
| 1 | enable | 234a86bf393cadeba1bcbc09a244a398ac10c23a51e7fd72d7c449ef0edaa9e9 |
+----+---------+------------------------------------------------------------------+
那么当使用下面的Python代码插入一行时
import MySQLdb
db = MySQLdb.connect(host='xxx.xxx.xxx.xxx', user='xxxx', passwd='xxxx', db='dbase')
c = db.cursor()
c.execute('INSERT IGNORE INTO `commands` (`input`, `inputhash`) VALUES (%s, %s)', ('enable', '234a86bf393cadeba1bcbc09a244a398ac10c23a51e7fd72d7c449ef0edaa9e9',))
我收到警告
Warning: Duplicate entry '234a86bf393cadeba1bcbc09a244a398ac10c23a51e7fd72d7c449ef0edaa9e9' for key 'inputhash'
c.execute('INSERT IGNORE INTO `commands` (`input`, `inputhash`) VALUES (%s, %s)', ('enable','234a86bf393cadeba1bcbc09a244a398ac10c23a51e7fd72d7c449ef0edaa9e9',))
为什么会这样?我认为在具有UNIQUE 字段的表上使用INSERT IGNORE 的全部目的是抑制错误并忽略写入尝试?
解决此问题的正确方法是什么?我想我可以使用warnings.filterwarnings('ignore') 抑制 Python 中的警告,但为什么首先出现警告?
【问题讨论】:
-
如果使用 IGNORE 修饰符,执行 INSERT 语句时发生的错误将被忽略。例如,如果没有 IGNORE,复制表中现有 UNIQUE 索引或 PRIMARY KEY 值的行会导致重复键错误并且语句被中止。使用 IGNORE,该行将被丢弃并且不会发生错误。忽略的错误会生成警告。 (dev.mysql.com/doc/refman/5.7/en/insert.html) 特别注意“忽略的错误会生成警告。”
-
那么,避免在数据库中存储重复数据的唯一“干净”方法(没有错误,没有警告)是关闭警告?!由于竞争条件,我无法检查该值是否已经存在(在我确定它不存在但在我写出我的值之前,有人可能会写出与我相同的值)。我试过锁定桌子,但也没有用。
标签: python mysql duplicates mysql-python