
本文旨在解决psycopg3中`executemany`方法批量插入多行数据时,针对`values %s`占位符与`on conflict`子句结合使用时遇到的常见`programmingerror`。我们将探讨如何正确构建包含多个列的`values`子句,提供两种解决方案:一种是基于字符串拼接的动态占位符生成,另一种是利用`psycopg.sql`模块进行更安全、更专业的sql语句组合,确保数据高效插入并妥善处理冲突。
在Psycopg3中,executemany方法是实现批量数据插入的推荐方式,它能够高效地执行多条相似的SQL语句。然而,与Psycopg2的execute_values不同,直接将SQL语句中的VALUES子句简单地写为VALUES %s,并期望它能自动展开为多列占位符,会导致ProgrammingError: the query has 1 placeholder but X parameters were passed。这是因为Psycopg3要求VALUES子句中的占位符数量必须与要插入的列数精确匹配。
例如,对于一个包含7列的表,如果尝试使用如下SQL和数据:
sql = """
INSERT INTO activities (type_, key_, a, b, c, d, e)
VALUES %s
ON CONFLICT (key_) DO UPDATE
SET
a = EXCLUDED.a,
b = EXCLUDED.b,
c = EXCLUDED.c,
d = EXCLUDED.d,
e = EXCLUDED.e
"""
values = [['type', 'key', None, None, None, None, None]] # 实际数据,每行7个元素
# cursor.executemany(sql, values)执行时会抛出ProgrammingError,因为VALUES %s只提供了一个占位符,而values列表中的每个子列表却提供了7个参数。为了解决这个问题,我们需要确保VALUES子句包含与列数相匹配的占位符。
最直接的方法是根据要插入的列数,动态生成形如(%s, %s, ..., %s)的VALUES子句。这种方法简单易懂,适用于SQL结构相对固定的场景。
核心思路:
示例代码:
import psycopg
# 假设这是你的原始SQL模板,其中包含一个占位符用于VALUES子句
# 注意:这里我们使用一个格式化字符串占位符 {} 来替换 VALUES 子句
base_sql_template = """
INSERT INTO activities (type_, key_, a, b, c, d, e)
VALUES {}
ON CONFLICT (key_) DO UPDATE
SET
a = EXCLUDED.a,
b = EXCLUDED.b,
c = EXCLUDED.c,
d = EXCLUDED.d,
e = EXCLUDED.e
"""
# 待插入的数据,每个子列表代表一行,包含7个元素
values_to_insert = [
['type1', 'key1', 1, 2, 3, 4, 5],
['type2', 'key2', 6, 7, 8, 9, 10],
['type3', 'key3', None, None, None, None, None]
]
if not values_to_insert:
print("没有数据可插入。")
else:
# 1. 获取列数(取第一行数据的长度)
num_columns = len(values_to_insert[0])
# 2. 生成占位符字符串,例如:'%s, %s, %s'
placeholders = ', '.join(['%s'] * num_columns)
# 3. 将占位符用括号括起来,形成 VALUES 子句,例如:'(%s, %s, %s)'
values_clause = f"({placeholders})"
# 4. 将 VALUES 子句注入到原始SQL模板中
final_sql = base_sql_template.format(values_clause)
print("生成的最终SQL语句示例:")
print(final_sql)
# 建立数据库连接并执行
try:
# 请替换为你的实际数据库连接信息
with psycopg.connect(dbname='test', user='your_user', password='your_password', host='localhost') as conn:
with conn.cursor() as cur:
cur.executemany(final_sql, values_to_insert)
conn.commit()
print(f"成功插入/更新 {len(values_to_insert)} 行数据。")
except psycopg.Error as e:
print(f"数据库操作失败: {e}")
注意事项:
Manus
全球首款通用型AI Agent,可以将你的想法转化为行动。
250
查看详情
对于更专业、更安全的SQL语句构建,Psycopg3提供了psycopg.sql模块。这个模块允许你以编程方式组合SQL片段,从而避免手动字符串拼接可能带来的SQL注入风险,并提高代码的可读性和可维护性。
核心思路:
示例代码:
import psycopg
from psycopg import sql
# 待插入的数据,每个子列表代表一行,包含7个元素
values_to_insert = [
['type1', 'key1', 1, 2, 3, 4, 5],
['type2', 'key2', 6, 7, 8, 9, 10],
['type3', 'key3', None, None, None, None, None]
]
if not values_to_insert:
print("没有数据可插入。")
else:
# 1. 获取列数
num_columns = len(values_to_insert[0])
# 2. 使用sql.Placeholder()生成与列数匹配的占位符列表
# sql.SQL(', ').join(...) 会将多个 sql.Placeholder() 用逗号连接
placeholders_sql = sql.SQL(', ').join(sql.Placeholder() * num_columns)
# 3. 构建完整的SQL语句,使用 {placeholders} 作为 VALUES 子句的占位符
# 注意:VALUES ({placeholders}) 中的括号是SQL语法的一部分
final_sql_obj = sql.SQL("""
INSERT INTO activities (type_, key_, a, b, c, d, e)
VALUES ({placeholders})
ON CONFLICT (key_) DO UPDATE
SET
a = EXCLUDED.a,
b = EXCLUDED.b,
c = EXCLUDED.c,
d = EXCLUDED.d,
e = EXCLUDED.e
""").format(placeholders=placeholders_sql) # 使用 .format() 注入动态生成的占位符
# 建立数据库连接并执行
try:
# 请替换为你的实际数据库连接信息
with psycopg.connect(dbname='test', user='your_user', password='your_password', host='localhost') as conn:
with conn.cursor() as cur:
# 打印生成的SQL语句(用于调试)
print("使用psycopg.sql生成的最终SQL语句示例:")
print(final_sql_obj.as_string(conn)) # as_string() 用于查看最终的SQL字符串
cur.executemany(final_sql_obj, values_to_insert)
conn.commit()
print(f"成功插入/更新 {len(values_to_insert)} 行数据。")
except psycopg.Error as e:
print(f"数据库操作失败: {e}")
优势:
在Psycopg3中使用executemany进行批量插入并处理冲突时,关键在于正确构建VALUES子句的占位符。
通过以上两种方法,你可以有效地在Psycopg3中利用executemany实现高效的批量数据插入和冲突处理。
以上就是Psycopg3高效批量插入与冲突处理:executemany的正确姿势的详细内容,更多请关注其它相关文章!
# 句中
# 阜阳网站建设推广方法
# 福建创新网站推广公司
# 网络诚信建设网站
# 拉萨seo服务
# 关键词优化排名的方式
# 西安最好的seo优化
# 三只松鼠网站推广方式
# 开封网站怎么推广
# 清河品质网站建设
# 皮影戏营销推广策略研究
# 这是
# word
# 中带
# 与非
# 解决问题
# 行数
# 两种
# 文档
# 多个
# 子句
# 防止sql注入
# sql语句
# sql注入
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
《红果免费短剧》下载观看方法
Golang中的rune与byte类型区别是什么_Golang字符与字节处理详解
键盘声音异常怎么回事_键盘异响怎么处理
4399造梦西游3无敌版_4399游戏入口
广州地铁app准妈咪徽章领取方法
C++如何使用CMake构建项目_C++ CMakeLists.txt编写入门教程
word页码灰色不能用如何解决
实现二叉树的层序插入:基于树大小的路径导航
mysql通配符能用于日志查询吗_mysql通配符在系统日志查询中的实际使用方法
Python中处理嵌套字典与列表的数据提取与过滤教程
《洛克王国:世界》国家队搭配攻略
在XML中嵌入二进制数据(如图片)的最佳实践是什么? Base64编码与解析注意事项
汽水音乐官网网页版入口 汽水音乐官网网页版在线入口
谷歌学术论文搜索引擎 谷歌学术官网入口论坛永久链接
Chart.js 教程:自定义插件实现图表与图例间距调整
diskgenius分区工具如何设置Bios启动项
晓晓优选app支付宝绑定方法
告别繁琐SEO!如何使用SyliusSitemap插件自动化生成网站地图,提升搜索引擎排名
c++20的指定初始化(Designated Initializers)怎么用_c++ C风格结构体初始化
CSS如何使用outline-offset与颜色组合突出元素边框
如何配置VS Code作为您Git操作的默认编辑器
win11怎么启用或禁用休眠 Win11 powercfg命令管理休眠文件【技巧】
《单词速记宝》设置学习计划方法
快手网页版官方访问 快手网页版页面在线打开
谷歌邮箱官方入口链接 谷歌邮箱网页版电脑端快速登录
优化Flask模板中SQLAlchemy查询迭代标签:处理字符串空格问题
泰拉瑞亚水晶无法放置问题
C++ priority_queue怎么用_C++优先队列底层实现与自定义比较器
CSS如何在页面中引入重置样式_使用Normalize.css或Reset.css统一浏览器默认样式
汽车之家网页版免费登录_汽车之家官网首页直接进入
手机自动关机是怎么回事?如何修复?手机异常关机的原因排查与修复技巧
哔哩哔哩在线观看入口 B站官网免费进入
《全民k歌》网页版最新登录入口一览
Teambition网盘如何共享文件
批改网网页版登录 批改网电脑版学生登录入口
《下一站江湖2》心法融合技巧
企查查官网和爱企查 企查查企业查询官网入口
Win10怎么设置快速启动 Win10开启快速启动设置方法
铁路12306怎么申请退票_铁路12306退票申请操作流程
Sublime Text怎么关闭自动完成_Sublime禁用Auto Complete设置
手机坏了微信聊天记录怎么导出来 新手机恢复聊天记录技巧
睡觉时心跳快是什么原因 夜间心悸如何应对
如何用mysql开发用户注册登录功能_mysql用户注册登录数据库设计
小红书如何引流到私信?引流到私信有用吗?
win11关机几秒又自己开机 Win11关机自动重启问题修复
iPhone 14 Pro如何更改区域设置_iPhone 14 Pro地区语言修改教程
VS Code快捷键when上下文子句的妙用
钉钉任务无法提醒如何处理 钉钉任务提醒优化方法
个人所得税办理入口 个人所得税综合所得年度汇算入口
纯CSS实现滚动时动态时间轴线条颜色填充效果
2025-11-10
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。