You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用For循环填充PostgreSQL数据表?解决仅插入首元素问题

解决PostgreSQL循环插入列表数据的问题

问题原因

你的代码存在几个核心问题:

  • id_num 在循环内部初始化,每次迭代都会重置为0,加1后始终是1,导致所有记录的ID重复,加上ON CONFLICT DO NOTHING,后续记录因ID冲突被跳过,只有第一条能插入成功。
  • 使用字符串格式化拼接SQL语句,存在SQL注入风险,且如果艺术家名称包含单引号等特殊字符会直接报错。
  • 未显式提交事务:PostgreSQL默认不会自动提交事务,执行插入后需要手动提交才能将数据持久化到数据库。

基础修正方案

把id_num的初始化移到循环外,使用参数化查询避免SQL注入,最后添加事务提交:

artist_name = ['Madonna', 'Slayer', 'Disturbed', 'Michael Jackson', 'Katty Parry']
with conn.cursor() as cur:
    id_num = 1  # 将初始化放到循环外部
    for artist in artist_name:
        # 使用参数化查询,%s是PostgreSQL的占位符
        cur.execute("""
            INSERT INTO Artist (Id, Name) 
            VALUES (%s, %s) 
            ON CONFLICT DO NOTHING
        """, (id_num, artist))
        id_num += 1
conn.commit()  # 提交事务,确保数据写入数据库

更高效的批量插入方案

如果数据量较大,循环单次插入效率较低,推荐使用executemany批量执行:

artist_name = ['Madonna', 'Slayer', 'Disturbed', 'Michael Jackson', 'Katty Parry']
# 生成包含ID和名称的元组列表
artist_data = [(idx + 1, name) for idx, name in enumerate(artist_name)]

with conn.cursor() as cur:
    cur.executemany("""
        INSERT INTO Artist (Id, Name) 
        VALUES (%s, %s) 
        ON CONFLICT DO NOTHING
    """, artist_data)
conn.commit()

额外建议

如果Artist表的Id字段是自增序列(比如用SERIAL或IDENTITY类型定义),完全不需要手动赋值ID,数据库会自动生成,代码可以简化为:

artist_name = ['Madonna', 'Slayer', 'Disturbed', 'Michael Jackson', 'Katty Parry']

with conn.cursor() as cur:
    cur.executemany("""
        INSERT INTO Artist (Name) 
        VALUES (%s) 
        ON CONFLICT DO NOTHING
    """, [(name,) for name in artist_name])
conn.commit()

内容的提问来源于stack exchange,提问作者Warxant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:42:36