[项目踩坑] py executemany 的使用报错:Not all parameters were used in the SQL
场景
使用 executemany 来执行批量操作
我的执行代码 如下:
with closing(ds.get_connection()) as conn, closing(conn.cursor()) as cur:
cur.executemany(sql, tup_list)
# cur.execute(sql, tup_list[0])
conn.commit()
其中数据为:
sql:INSERT INTO
football_player_top_data(
id,
competition_id,
season,
team,
goals,
penalties,
assists,
created_at) VALUES (%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE
team=%s,
goals=%s,
penalties=%s,
assists=%s,
created_at=%s
tuplist:
[(63861, 2, '2019-2020', 1612, 1, 0, 0, '2020-05-29 15:01:32', 1612, 1, 0, 0, '2020-05-29 15:01:32'), (63978, 2, '2019-2020', 188, 1, 0, 0, '2020-05-29 15:01:32', 188, 1, 0, 0, '2020-05-29 15:01:32'), (64119, 2, '2019-2020', 207, 1, 0, 0, '2020-05-29 15:01:32', 207, 1, 0, 0, '2020-05-29 15:01:32'), (64153, 2, '2019-2020', 1612, 1, 0, 0, '2020-05-29 15:01:32', 1612, 1, 0, 0, '2020-05-29 15:01:32'), (68935, 2, '2019-2020', 3193, 1, 0, 0, '2020-05-29 15:01:32', 3193, 1, 0, 0, '2020-05-29 15:01:32'), (79870, 2, '2019-2020', 206, 1, 0, 0, '2020-05-29 15:01:32', 206, 1, 0, 0, '2020-05-29 15:01:32'), (81138, 2, '2019-2020', 201, 1, 0, 0, '2020-05-29 15:01:32', 201, 1, 0, 0, '2020-05-29 15:01:32'), (84144, 2, '2019-2020', 201, 0, 1, 0, '2020-05-29 15:01:32', 201, 0, 1, 0, '2020-05-29 15:01:32'), (90162, 2, '2019-2020', 204, 1, 0, 0, '2020-05-29 15:01:32', 204, 1, 0, 0, '2020-05-29 15:01:32'), (97156, 2, '2019-2020', 3195, 1, 0, 0, '2020-05-29 15:01:32', 3195, 1, 0, 0, '2020-05-29 15:01:32'), (97236, 2, '2019-2020', 207, 1, 0, 0, '2020-05-29 15:01:32', 207, 1, 0, 0, '2020-05-29 15:01:32'), (97401, 2, '2019-2020', 181, 1, 0, 0, '2020-05-29 15:01:32', 181, 1, 0, 0, '2020-05-29 15:01:32'), (97645, 2, '2019-2020', 3195, 1, 0, 0, '2020-05-29 15:01:32', 3195, 1, 0, 0, '2020-05-29 15:01:32'), (107413, 2, '2019-2020', 193, 1, 0, 0, '2020-05-29 15:01:32', 193, 1, 0, 0, '2020-05-29 15:01:32'), (120408, 2, '2019-2020', 206, 1, 0, 0, '2020-05-29 15:01:32', 206, 1, 0, 0, '2020-05-29 15:01:32'), (121546, 2, '2019-2020', 188, 1, 0, 0, '2020-05-29 15:01:32', 188, 1, 0, 0, '2020-05-29 15:01:32'), (127225, 2, '2019-2020', 201, 0, 1, 0, '2020-05-29 15:01:32', 201, 0, 1, 0, '2020-05-29 15:01:32'), (130167, 2, '2019-2020', 209, 2, 0, 0, '2020-05-29 15:01:32', 209, 2, 0, 0, '2020-05-29 15:01:32'), (139192, 2, '2019-2020', 209, 2, 0, 0, '2020-05-29 15:01:32', 209, 2, 0, 0, '2020-05-29 15:01:32'), (142059, 2, '2019-2020', 206, 1, 0, 0, '2020-05-29 15:01:32', 206, 1, 0, 0, '2020-05-29 15:01:32'), (142654, 2, '2019-2020', 196, 1, 0, 0, '2020-05-29 15:01:32', 196, 3415, 1, 0, 0, '2020-05-29 15:01:32', 3415, 1, 0, 0, '2020-05-29 15:01:32')]
报错提示信息
Not all parameters were used in the SQL statement
分析提示信息 过程
翻译:为 参数不够?
通过仔细对比,仔细排查,发现是一样的
那我该用 execute 来试试?就插入一条。
with closing(ds.get_connection()) as conn, closing(conn.cursor()) as cur:
cur.execute(sql, tup_list[0])
conn.commit()
发现直接成功。。。。
排除参数 不够的情况
去百度搜索看看
发现 都是一毛一样的文章!!!我草。
而且告诉我 :
在这里executemany和ON DUPLICATE KEY UPDATE联合使用的时候如果按照sql常规模式,即:sql=”insert into myTable (created_day,name,count) values(%s,%s,%s) ON DUPLICATE KEY UPDATE count=count+%s”会报bug:not all arguments converted during string formatting
不理解 UPDATE count=count+%s
的写法是什么意思?
去google 看看,要输入英文的才行。
搜索词:
Executemany and duplicate
找到下面这个文章:
Executemany insert on duplicate key update error: Not all parameters were used
最终发现,
解决方案
原理
在pymysql的 executemany
不能使用位置参数来表示实际的列名。出于多种原因,列名需要在语句中进行硬编码。但是,在您的情况下,我认为这样做没有任何问题:
代码
INSERT INTO updates (ID, insert_datetime, egroup, job_state)
VALUES (%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE
insert_datetime = VALUES(insert_datetime),
egroup = VALUES(egroup),
job_state = VALUES(job_state);
或者,作为Python代码:
sql = "INSERT INTO updates (ID, insert_datetime, egroup, job_state) VALUES (%s,%s,%s,%s) ON DUPLICATE KEY UPDATE insert_datetime = VALUES(insert_datetime), egroup = VALUES(egroup), job_state = VALUES(job_state);"
mycursor.executemany(sql, jobUpdatesList)
分析
在代码
ON DUPLICATE KEY UPDATE insert_datetime = VALUES(insert_datetime), egroup = VALUES(egroup),
这里, insert_datetime = VALUES(insert_datetime)
意思是 我们不需要指定 %s
这么去替换。
我们直接给一个名字,pymysql 自己会去找到对应的值。
不需要重复的写。
所以我的正确代码 附上。
代码
with closing(ds.get_connection()) as conn, closing(conn.cursor()) as cur:
cur.executemany(sql, tup_list)
# cur.execute(sql, tup_list[0])
conn.commit()
数据
tuplist:
[(63861, 2, '2019-2020', 1612, 1, 0, 0, '2020-05-29 15:12:35'), (63978, 2, '2019-2020', 188, 1, 0, 0, '2020-05-29 15:12:35'), (64119, 2, '2019-2020', 207, 1, 0, 0, '2020-05-29 15:12:35'), (64153, 2, '2019-2020', 1612, 1, 0, 0, '2020-05-29 15:12:35'), (68935, 2, '2019-2020', 3193, 1, 0, 0, '2020-05-29 15:12:35'), (79870, 2, '2019-2020', 206, 1, 0, 0, '2020-05-29 15:12:35'), (81138, 2, '2019-2020', 201, 1, 0, 0, '2020-05-29 15:12:35'), (84144, 2, '2019-2020', 201, 0, 1, 0, '2020-05-29 15:12:35'), (90162, 2, '2019-2020', 204, 1, 0, 0, '2020-05-29 15:12:35'), (97156, 2, '2019-2020', 3195, 1, 0, 0, '2020-05-29 15:12:35'), (97236, 2, '2019-2020', 207, 1, 0, 0, '2020-05-29 15:12:35'), (97401, 2, '2019-2020', 181, 1, 0, 0, '2020-05-29 15:12:35'), (97645, 2, '2019-2020', 3195, 1, 0, 0, '2020-05-29 15:12:35'), (107413, 2, '2019-2020', 193, 1, 0, 0, '2020-05-29 15:12:35'), (120408, 2, '2019-2020', 206, 1, 0, 0, '2020-05-29 15:12:35'), (121546, 2, '2019-2020', 188, 1, 0, 0, '2020-05-29 15:12:35'), (127225, 2, '2019-2020', 201, 0, 1, 0, '2020-05-29 15:12:35'), (130167, 2, '2019-2020', 209, 2, 0, 0, '2020-05-29 15:12:35'), (139192, 2, '2019-2020', 209, 2, 0, 0, '2020-05-29 15:12:35'), (142059, 2, '2019-2020', 206, 1, 0, 0, '2020-05-29 15:12:35'), (142654, 2, '2019-2020', 196, 1, 0, 0, '2020-05-29 15:12:35'), (142934, 2, '2019-2020', 188, 1, 0, 0, '2020-05-29 15:12:35'), (151438, 2, '2019-2020', 203, 1, 0, 0, '2020-05-29 15:12:35'), (184119, 2, '2019-2020', 3415, 1, 0, 0, '2020-05-29 15:12:35')]
sql:
INSERT INTO `football_player_top_data` (`id`,`competition_id`,`season`,`team`,`goals`,`penalties`,`assists`,`created_at`) VALUES (%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE `team`=values(team),`goals`=values(goals),`penalties`=values(penalties),`assists`=values(assists),`created_at`=values(created_at)
提示信息
来看看数据库,果然有了。
小结
今天的坑 主要是 使用 executemany
的硬转码问题。
一般人没踩过或者没去google 都很难找到问题。
由此可见,百度的某些爬虫文章,太坑了。根本没有解决问题,就是爬。
还是要多看手册,多google看看。
防爬虫说明
禁止 学习某地爬虫,知乎爬虫,CSDN 爬虫。
本文,首发在 learnku 社区。
@author
汪春波(www.shxdledu.cn)
本作品采用《CC 协议》,转载必须注明作者和本文链接