【发布时间】: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