postgresql:\ copy方法输入有效条目并丢弃异常

时间:2013-11-23 23:48:34

标签: sql postgresql commit

输入以下命令时:

\copy mmcompany from '<path>/mmcompany.txt' delimiter ',' csv;

我收到以下错误:

ERROR: duplicate key value violates unique constraint "mmcompany_phonenumber_key"

我理解为什么会这样,但是我如何以插入有效条目的方式执行命令,并且会丢弃那些产生错误的命令?

2 个答案:

答案 0 :(得分:5)

PostgreSQL不这样做的原因与它如何实现约束和验证有关。当约束失败时,它会导致事务中止。交易处于不洁净状态,无法恢复。

可以为每一行创建一个新的子事务,但这非常慢,并且首先违背了使用COPY的目的,因此COPY中的PostgreSQL不支持它。这次。您可以在PL / PgSQL中自己使用BEGIN ... EXCEPTION块内的LOOP块,从复制到临时表中的数据中选择。这种方法效果很好但可能很慢。

如果可能的话,最好在执行任何违反它们的插入之前使用SQL检查约束。这样你就可以:

CREATE TEMPORARY TABLE stagingtable(...);

\copy stagingtable FROM 'somefile.csv'

INSERT INTO realtable
SELECT * FROM stagingtable
WHERE check_constraints_here;

但是请记住并发问题。如果您尝试通过COPY进行合并/ upsert,则必须 LOCK TABLE realtable;在您的交易开始时,您仍然可能会出错。看起来这就是你要做的事情 - copy if not exists。如果是这样,跳过错误绝对是错误的方法。参见:

......这是一个备受争议的问题。

答案 1 :(得分:2)

处理约束违规的一种方法是在目标表上定义触发器以处理错误。这并不理想,因为仍然存在竞争条件(如果同时加载),并且触发器具有相当高的开销。

另一种方法:将COPY复制到临时表中,并使用SQL将数据加载到目标表中,并进行一些处理以跳过现有条目。

此外,另一种有用的方法是使用pgloader