我想将一些数据更新/插入MySQL。这是我的代码段:
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
更改为unique和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'
当我立即执行两次代码时,会发生此错误。如果我运行代码并等待片刻然后运行代码,则不会出错!
答案 0 :(得分:0)
您必须将一个字段指定为唯一字段,并使用插入和重复更新作为单个查询。如果唯一字段不存在,该语句将插入,否则它将更新现有字段。 参考:https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html