2009-11-26 61 views
2

我正在寻找一种简单的方法来查询更新或插入的基础上,如果该行在第一位存在。我正在尝试使用Python的MySQLdb。 这是我执行我的查询:Python MySQLdb:更新如果存在,否则插入

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

我已经看到了四种方式来实现这一点:

  1. 重复键。不幸的是,主键已经作为唯一的ID使用,所以我不能使用它。

  2. REPLACE。同上,我相信它依靠主键正常工作。

  3. mysql_affected_rows()。通常你可以在更新行后使用它来查看是否有任何事情受到影响。我不相信Python中的MySQLdb支持这个功能。

  4. 当然最后的努力:做一个SELECT查询,fetchall,然后根据结果更新或插入。基本上我只是试图将查询保持在最低限度,所以2个查询而不是1个现在不太理想。

基本上我想知道如果我错过任何其他方式来完成这个选项之前去与选项4.感谢您的时间。

+0

快速和肮脏的方式可能是,'试试:update_query,除了︰insert_query' – YOU

+0

我也试过这个。如果更新无法找到任何匹配项,则不会引发异常。 :( – Chuck

+1

请勿使用'format()'来创建您的查询。请按照http://www.python.org/dev/peps/pep-0249/中所述使用参数绑定。 – 2009-11-26 08:13:32

回答

2

Mysql DOES允许您拥有唯一的索引,并且INSERT ... ON DUPLICATE UPDATE将执行更新,如果任何唯一索引具有重复的,而不仅仅是PK。

但是,我可能仍然会采用“两种查询”方法。你在交易中这样做,对吧?

  1. 执行更新
  2. 检查行受到影响,如果是0,则做插入

OR

  1. 尝试插入
  2. 如果它失败了,因为独特的索引违规,做更新(注意:你会想检查错误代码,以确保它没有因为某些其他原因而失败)

如果行通常已经存在,但前者很好,但如果在事务外执行该操作,或者隔离模式不够高,则会导致竞争(或死锁)。

在库存表中为item_number创建一个唯一索引听起来对我来说是个好主意,因为我想象(不知道您的模式的细节)一个项目应该只有一个库存级别(假设您的系统没有'允许多个库存地点等)。

相关问题