Python MySQLdb: 存在则更新,否则插入

3 投票
1 回答
5715 浏览
提问于 2025-04-15 16:24

我想找一个简单的方法来查询是否需要更新或插入数据,前提是这行数据是否存在。我现在正在使用Python的MySQLdb库来实现这个功能。以下是我执行查询的方式:

self.cursor.execute("""UPDATE `inventory`
                          SET `quantity` = `quantity`+{1}
                        WHERE `item_number` = {0}
                    """.format(item_number,quantity));

我看到有四种方法可以做到这一点:

  1. 使用DUPLICATE KEY。可惜的是,主键已经被用作唯一ID,所以我不能用这个方法。

  2. 使用REPLACE。和上面一样,我觉得这个方法也依赖于主键才能正常工作。

  3. mysql_affected_rows()。通常在更新行之后可以用这个函数来查看是否有任何数据被影响。不过,我认为Python的MySQLdb不支持这个功能。

  4. 当然还有最后的办法:先执行一个SELECT查询,获取所有结果,然后根据结果来决定是更新还是插入。基本上,我只是想尽量减少查询次数,所以现在两个查询而不是一个查询并不是最理想的选择。

总的来说,我在想在选择第四种方法之前,是否还有其他方法可以做到这一点。谢谢你的时间。

1 个回答

2

MySQL确实允许你创建唯一索引,如果你使用INSERT ... ON DUPLICATE UPDATE语句,当有重复的唯一索引时,它会进行更新,而不仅仅是主键。

不过,我还是建议你使用“两条查询”的方法。你是在一个事务中进行操作,对吧?

  1. 先进行更新
  2. 检查受影响的行数,如果是0,那就进行插入

或者

  1. 尝试插入数据
  2. 如果因为唯一索引冲突而失败,那就进行更新(注意:你需要检查错误代码,确保不是因为其他原因失败)

第一种方法适合大多数情况下行已经存在的情况,但如果你在事务外进行操作,或者隔离级别不够高,可能会导致竞争条件(或者死锁)。

在你的库存表中为item_number创建唯一索引听起来是个好主意,因为我想(虽然不知道你具体的数据库结构)一个商品应该只有一个库存水平(假设你的系统不允许多个库存地点等)。

撰写回答