【问题标题】:Mysql query does not Update the same recordmysql查询不更新同一条记录
【发布时间】:2019-03-12 04:43:18
【问题描述】:

我想更新/插入一些数据到 MySQL。这是我的代码 sn-p:

import requests
from lxml import html
from bs4 import BeautifulSoup
import mysql.connector
import datetime

Host_Auction = 'MY_URL/live_data.json'

def Get_Json_From_Url():
        resp = requests.get(url=Host_Auction)
        data = resp.json()
        return data

def Update_Portal(server_data):
        """ Connect to MySQL database """
        conn = mysql.connector.connect(host=DBhost,database=DBname,user=DBusername,password=DBpassword)

        cursor = conn.cursor()
        ##Update Prices on portal
        for index in server_data:
          query = """UPDATE tblproducts 
                     SET updated_at  = %s                     
                     WHERE gid=21 AND configoption1 like '%auction%' AND configoption2 like %s """

          query_data =(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%d"),"%"+str(index['key'])+"%")          
          cursor.execute(query, query_data)
          conn.commit()


          print ("Update: ", cursor.rowcount, index['key'])
          if (cursor.rowcount == 0):
              cursor = conn.cursor()
              query= """INSERT INTO `tblproducts`
                        VALUES (null,'server',21,%s,%s,0,0,0,0,0,0,0,0,'recurring',0,'','','',0,
                        'auction',%s,'','','','','','','','','','','','','','','','','','','',''
                        ,'','','','','',0,0,0,0,'',0,'',0,0,0,0,0,0,'',0,0,0,0,%s,%s) """

              query_data =(index['name']+"("+str(index['key'])+")",index['description'][0]+"\n"+index['description'][1],str(index['key']),datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%d"),datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%d"))
              cursor.execute(query, query_data)
              conn.commit()

        conn.close()

if __name__ == '__main__':
        json_data_=Get_Json_From_Url()
        Update_Portal(json_data_['server'])

使用上面的代码,我希望如果一行在表中,则更新它,如果它在表中不存在,则插入一个新行。对于第一次运行,不执行更新查询,只执行插入查询。并且在第一次运行之后,当变量server_data 与之前相同时,所有行都应该被更新并且不应该插入新行。但是当我多次运行代码时,它会在表中插入新行而不是更新!我在每个 cursor.execute() 之后 commit() 来解决这个问题,但它没有帮助。我正在使用 mysql.connector,操作系统是 linux,mysql 作为 docker 容器运行。表结构如下:

CREATE TABLE `tblproducts` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
 `type` text NOT NULL,
 `gid` int(10) NOT NULL,
 `name` text NOT NULL,
 `description` text NOT NULL,
 `hidden` tinyint(1) NOT NULL,
 `showdomainoptions` tinyint(1) NOT NULL,
 `welcomeemail` int(10) NOT NULL DEFAULT 0,
 `stockcontrol` tinyint(1) NOT NULL,
 `qty` int(10) NOT NULL DEFAULT 0,
 `proratabilling` tinyint(1) NOT NULL,
 `proratadate` int(2) NOT NULL,
 `proratachargenextmonth` int(2) NOT NULL,
 `paytype` text NOT NULL,
 `allowqty` int(1) NOT NULL,
 `subdomain` text NOT NULL,
 `autosetup` text NOT NULL,
 `servertype` text NOT NULL,
 `servergroup` int(10) NOT NULL,
 `configoption1` text NOT NULL,
 `configoption2` text NOT NULL,
 `configoption3` text NOT NULL,
 `configoption4` text NOT NULL,
 `configoption5` text NOT NULL,
 `configoption6` text NOT NULL,
 `configoption7` text NOT NULL,
 `configoption8` text NOT NULL,
 `configoption9` text NOT NULL,
 `configoption10` text NOT NULL,
 `configoption11` text NOT NULL,
 `configoption12` text NOT NULL,
 `configoption13` text NOT NULL,
 `configoption14` text NOT NULL,
 `configoption15` text NOT NULL,
 `configoption16` text NOT NULL,
 `configoption17` text NOT NULL,
 `configoption18` text NOT NULL,
 `configoption19` text NOT NULL,
 `configoption20` text NOT NULL,
 `configoption21` text NOT NULL,
 `configoption22` text NOT NULL,
 `configoption23` text NOT NULL,
 `configoption24` text NOT NULL,
 `freedomain` text NOT NULL,
 `freedomainpaymentterms` text NOT NULL,
 `freedomaintlds` text NOT NULL,
 `recurringcycles` int(2) NOT NULL,
 `autoterminatedays` int(4) NOT NULL,
 `autoterminateemail` int(10) NOT NULL DEFAULT 0,
 `configoptionsupgrade` tinyint(1) NOT NULL,
 `billingcycleupgrade` text NOT NULL,
 `upgradeemail` int(10) NOT NULL DEFAULT 0,
 `overagesenabled` varchar(10) NOT NULL,
 `overagesdisklimit` int(10) NOT NULL,
 `overagesbwlimit` int(10) NOT NULL,
 `overagesdiskprice` decimal(6,4) NOT NULL,
 `overagesbwprice` decimal(6,4) NOT NULL,
 `tax` tinyint(1) NOT NULL,
 `affiliateonetime` tinyint(1) NOT NULL,
 `affiliatepaytype` text NOT NULL,
 `affiliatepayamount` decimal(10,2) NOT NULL,
 `order` int(10) NOT NULL DEFAULT 0,
 `retired` tinyint(1) NOT NULL,
 `is_featured` tinyint(1) NOT NULL,
 `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 PRIMARY KEY (`id`),
 KEY `gid` (`gid`),
 KEY `name` (`name`(64))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT

我将列 configoption2 更改为唯一和 INT(10)。现在使用上面的代码,我得到以下异常:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/mysql/connector/connection_cext.py", line 377, in cmd_query
    raw_as_string=raw_as_string)
_mysql_connector.MySQLInterfaceError: Duplicate entry '920333' for key 'configoption2'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./Update_Hetzner_Auction.py", line 139, in <module>
    Update_Portal(json_data_['server'])
  File "./Update_Hetzner_Auction.py", line 108, in Update_Portal
    cursor.execute(query, query_data)
  File "/usr/local/lib/python3.5/dist-packages/mysql/connector/cursor_cext.py", line 264, in execute
    raw_as_string=self._raw_as_string)
  File "/usr/local/lib/python3.5/dist-packages/mysql/connector/connection_cext.py", line 380, in cmd_query
    sqlstate=exc.sqlstate)
mysql.connector.errors.IntegrityError: 1062 (23000): Duplicate entry '920333' for key 'configoption2'

当我立即执行两次代码时会发生此错误。如果我运行代码并等待片刻然后运行代码,它不会出错!

【问题讨论】:

  • 我建议您将 conn.commit() 移到 foor 循环之外
  • 起初con.commit()for 循环之外,我知道它有更好的性能。但我认为问题是因为这个所以把它放在每个execute 之后。我认为这与性能有关,而不是我的问题,对吧?
  • @Sinai:您的问题只需要使用英语。请用英文正确的值“ﺱﺭﻭﺭﺎﺨﺘﺻﺎﺻی”进行编辑。
  • 我编辑了我的问题并没有删除任何英文字符串。
  • @Sinai:请分享您的表结构和完整的程序以及发生的确切错误\问题。

标签: python mysql mysql-python


【解决方案1】:

您必须将字段指定为唯一的,并将插入和重复更新用作单个查询。如果唯一字段不存在,该语句将插入,否则它将更新现有的。 参考:https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html

【讨论】:

  • 我将字段 configoption2 更改为 unique 和 INT(10)。并按照您的建议更改了查询。它有时更新,有时插入,但由于ON DUPLICATE KEY 没有插入相等的行。但问题是我需要最后更新或插入行的id。如何获得最后修改的行 ID?
  • 如果表包含 AUTO_INCREMENT 列并且 INSERT ... UPDATE 插入一行,LAST_INSERT_ID() 函数将返回 AUTO_INCREMENT 值。如果该语句改为更新一行,则 LAST_INSERT_ID() 没有意义。但是,您可以使用 LAST_INSERT_ID(expr) 解决此问题。假设 id 是 AUTO_INCREMENT 列。要使 LAST_INSERT_ID() 对更新有意义,请按如下方式插入行:示例:INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;那么你可以通过last_insert_id获取最新插入/更新行的id。
  • 只需使用 ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id) 这将使您能够在 last_insert_id 中获取更新的字段。使用 mysql last insert id 得到相同的结果。
  • 谢谢。我会试一试的。
猜你喜欢
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
相关资源
最近更新 更多