勺子插入 postgres 会产生“重复键值违反唯一约束”

Posted

技术标签:

【中文标题】勺子插入 postgres 会产生“重复键值违反唯一约束”【英文标题】:Spoon inserting into postgres yields "duplicate key value violates unique constraint" 【发布时间】:2014-04-25 16:37:22 【问题描述】:

我在 PosgreSQL 9.1.13 中有一个表,我想用 MSSQL 中的数据填充它。为此,我使用 PDI 4.4.0。

Postgres 和 PDI 都在 Ubuntu 13.10 中运行。

Postgres 中的表格如下:

create table cobra.facultad (
    id_facultad serial primary key,
    nombre varchar(100),
    id_estado int4 references cobra.estado(id_estado),
    ultima_modificacion_usuario varchar(100),
    ultima_modificacion_fecha timestamp not null default current_timestamp
);

我的步骤是:

    表格输入 1:从 MSSQL 视图中选择不同并检索 nombre 列。 表格输入 2:在 Postgres 中选择与 cobra.facultad 不同的表格并检索 nombre 列。 合并行:合并两个通过nombre比较的流并获得flagfield,以确定它是新的、相同的还是已删除的。 合并后同步 Postgres 表,包括更新字段 nombre 列。

如果目标表为空,则测试完美。但是,如果它包含任何数据,我会得到以下异常:

2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : Because of an error, this step can't continue: 
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : org.pentaho.di.core.exception.KettleException: 
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : Error inserting row into table [facultad] with values: [1], [Fac. Educación a Distancia], [new]
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : 
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : Error inserting/updating row
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : ERROR: llave duplicada viola restricción de unicidad «facultad_pkey»
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :   Detail: Ya existe la llave (id_facultad)=(1).
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : 
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : 
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.pentaho.di.trans.steps.synchronizeaftermerge.SynchronizeAfterMerge.lookupValues(SynchronizeAfterMerge.java:484)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.pentaho.di.trans.steps.synchronizeaftermerge.SynchronizeAfterMerge.processRow(SynchronizeAfterMerge.java:881)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.pentaho.di.trans.step.RunThread.run(RunThread.java:50)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at java.lang.Thread.run(Thread.java:744)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : Caused by: org.pentaho.di.core.exception.KettleDatabaseException: 
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : Error inserting/updating row
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : ERROR: llave duplicada viola restricción de unicidad «facultad_pkey»
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :   Detail: Ya existe la llave (id_facultad)=(1).
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : 
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.pentaho.di.core.database.Database.insertRow(Database.java:1411)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.pentaho.di.core.database.Database.insertRow(Database.java:1325)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.pentaho.di.trans.steps.synchronizeaftermerge.SynchronizeAfterMerge.lookupValues(SynchronizeAfterMerge.java:142)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    ... 3 more
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) : Caused by: org.postgresql.util.PSQLException: ERROR: llave duplicada viola restricción de unicidad «facultad_pkey»
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :   Detail: Ya existe la llave (id_facultad)=(1).
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2077)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1810)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:498)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:386)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:332)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    at org.pentaho.di.core.database.Database.insertRow(Database.java:1360)
2014/04/25 13:11:51 - Sync Facultad.0 - ERROR (version 4.4.0-stable, build 17588 from 2012-11-21 16.02.21 by buildguy) :    ... 5 more

这意味着即使列id_facultad未指定用于插入/更新,spoon 也会尝试将其插入值为 1。

最奇怪的是,如果我再次运行测试,我会得到相同的错误,但现在值为 2。我得到相同的错误,直到它达到应该是表的主键序列 nextval。

接下来我尝试的自然是添加序列步骤。首先,我将其配置为读取序列的下一个值,然后将其放在 MergeSync 步骤之间,最后添加要插入/更新的 id_facultad 列。

结果是一样的...添加序列根本不读取序列。它从 1 开始并在后续运行中递增。

除了救命!

我无话可说

谢谢!

【问题讨论】:

您确定Merge rows (diff) 步骤的两个输入流都已排序吗? 【参考方案1】:

SERIAL 类型仅表示id_facultad 指向一个从 1 开始的序列。每次从该序列中检索一个值时,下一个值都会递增。

如果您为id_facultad 插入自己的值,则有责任将序列更新为下一个未使用的数字。试试:

ALTER SEQUENCE id_facultad_seq RESTART WITH (
    SELECT 1+MAX(id_facultad)
    FROM cobra.facultad
);

【讨论】:

感谢您的回答!。我没有尝试插入我自己的id_facultad 值。在我第一次尝试时,我什至根本没有检索到该列,以为勺子不会尝试自行插入它。在我的第二次尝试中,我尝试使用 Add Sequence 步骤从 Postgres 读取序列,并检查 Use DB to generate the sequence 选项。干杯。 你是对的,问题与水壶无关......这是在尝试转换之前插入数据的方式。 id_facultad 实际上是在初始 insert 语句中指定的。非常感谢!

以上是关于勺子插入 postgres 会产生“重复键值违反唯一约束”的主要内容,如果未能解决你的问题,请参考以下文章

百味勺子——环境搭建篇

Pentaho:水壶/勺子:插入后组合多个数据

如果某些数据丢失,Postgres 会自动插入以前的值

防止在 postgres 上的异步插入重复

postgres:更新冲突插入行并返回旧值

如何使用 node-postgres 将多行正确插入 PG?