如何用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
相关产品推荐
相关产品推荐

