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

Postgres插入数据时如何按指定字段校验仅插入不存在的新记录

PostgreSQL跨表插入去重实现方案

方案1:使用ON CONFLICT特性(推荐,并发安全)

这是PostgreSQL特有的UPSERT语法,性能最高,并发场景下也不会出现重复插入问题,使用前需要先为判断重复的三个字段组合创建唯一约束:

-- 为table2创建三个字段组合的唯一约束
ALTER TABLE table2 ADD CONSTRAINT uk_table2_name_source_sink UNIQUE ("Name", "Source_NE", "Sink_NE");

修改你的Python代码中INSERT语句,增加冲突跳过逻辑即可,完整代码如下:

cursor_local.execute("""SELECT "Name", "Level_Capacity", "Source_NE", "Sink_NE" FROM "table1" WHERE "Name" LIKE '%WDM%' """)
rows = cursor_local.fetchall()

psycopg2.extras.execute_batch(cursor_local, 
'''INSERT INTO table2("Name", "Level_Capacity", "Source_NE", "Sink_NE") 
VALUES (%s, %s, %s, %s) 
-- 三个字段组合冲突时直接跳过插入
ON CONFLICT ("Name", "Source_NE", "Sink_NE") DO NOTHING''', 
(*rows,) )
connection_local.commit()

方案2:使用INSERT ... WHERE NOT EXISTS(无需修改表结构)

如果不方便修改table2的表结构添加唯一约束,可以用此方案,仅适合单线程无并发插入的场景:

cursor_local.execute("""SELECT "Name", "Level_Capacity", "Source_NE", "Sink_NE" FROM "table1" WHERE "Name" LIKE '%WDM%' """)
rows = cursor_local.fetchall()

psycopg2.extras.execute_batch(cursor_local, 
'''INSERT INTO table2("Name", "Level_Capacity", "Source_NE", "Sink_NE") 
SELECT %s, %s, %s, %s
WHERE NOT EXISTS (
    SELECT 1 FROM table2 
    WHERE "Name" = %s 
      AND "Source_NE" = %s 
      AND "Sink_NE" = %s
)''', 
# 参数按顺序对应,三个判断字段需要传两次
[(row[0], row[1], row[2], row[3], row[0], row[2], row[3]) for row in rows] )
connection_local.commit()

注意事项

如果Name/Source_NE/Sink_NE三个字段存在NULL值,PostgreSQL默认唯一约束会将两个NULL判定为不相等,若需要将NULL视为相同值做去重,可以将唯一约束替换为带COALESCE的唯一索引:

-- 替换NULL_PLACEHOLDER为业务中不会出现的占位字符串即可
CREATE UNIQUE INDEX idx_table2_unique_combine ON table2 (
    "Name", 
    COALESCE("Source_NE", 'NULL_PLACEHOLDER'), 
    COALESCE("Sink_NE", 'NULL_PLACEHOLDER')
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:06:04