python-3.x - Psycopg2 用一个查询插入多行
问题描述
我在 postgresql 中有带有字段id
(唯一)和val
. 我想执行这样的事情:
INSERT INTO my_table (id, val)
VALUES (%(id)s, %(val)s)
ON CONFLICT(id) DO UPDATE
SET val = val + %(val)s
要插入的数据就像[{"id": 123, "val": 5}, {"id": 456, "val": 8}, ...]
. 有没有办法通过一个查询来更新所有这些?
cursor.executemany
不会,这与在一个循环中使用所有这些字典进行查询是一样的。如果没有 ON CONFLICT DO UPDATE 我可以做类似的事情"insert into mytable (id, val) values " + ', '.join(['(%s, %s)'] * len(data))
并将数据转换到列表 [id1, val1, id2, val2, ...]。但我不知道如何组合多个值来插入和更新语句。
解决方案
I have the same problem. After a while searching, I found two post:
- Posgresql - upsert: https://dba.stackexchange.com/questions/167591/postgresql-psycopg2-upsert-syntax-to-update-columns
- Psycopg2 - insert many rows: psycopg2: insert multiple rows with one query
=> So the answer for you is:
# my table: cas(address, id, description) - address is primary key
data = [('0x18f9f00a432F50c6E2429d31776724d3cB873BEF', '1000', 'mot ngan'),
('0x06471C53CE649Eb4dA88b792D500544A7E5C9635', '2000', 'hai ngan')]
args = [cur.mogrify('(%s, %s, %s)', x).decode('utf-8')
for x in data]
args_str = ', '.join(args)
cur.execute('''INSERT INTO cas (address, id, description) VALUES'''
+ args_str +
'''ON CONFLICT (address) DO UPDATE SET
(address, id, description) = (EXCLUDED.address, EXCLUDED.id, EXCLUDED.description)''')
推荐阅读
- c++ - 如何使 Visual Studio 中的 vcpkg 忽略特定库
- python - 从 Anaconda 中删除 pkgs 文件?
- haskell - 表征可以接受 `()` 作为输入的函数类型(不进行单态化)
- c# - ASP.NET Core 5:外键将唯一约束添加到依赖表作为阴影属性
- python - 将 OpenCV GPUMat 作为张量输入 PyTorch 网络
- pandas - 如何根据自定义顺序对 pandas 多索引数据框的索引进行排序
- ios - Swift 等待异步回调完成以进行清理
- javascript - 两个图表的弹性框溢出屏幕
- kiwi-tcms - 是否可以对 kiwi-tcms 表执行查询?
- json - 使用 JSON_QUERY 提取