使用外键将表加载到PostgreSQL中会产生错误

时间:2013-08-31 18:11:36

标签: xml postgresql foreign-keys

我正在使用SymmetricDS数据库复制软件跨数据库复制表。

我为PostgreSQL创建了这个XML定义表,我已经创建了它:

<table name="ServiceItem">
  <column name="ServiceItemID" type="INTEGER" required="true" primaryKey="true"/>
  <column name="ParentItemID"  type="INTEGER" />

  <foreign-key name="FK_ServiceItem_ServiceItem" foreignTable="ServiceItem">
      <reference local="ServiceItemID" foreign="ParentItemID" />
  </foreign-key>
</table>

我希望parentItemID列中必须存在所有ServiceItemID值,这就是外键的关键点。

但是当我加载它时,我从SymmetricDS中收到此错误:

[] - JdbcSqlTemplate - ERROR: there is no unique constraint matching given keys 
for referenced table "ServiceItem".  Failed to execute: ALTER TABLE "ServiceItem"
ADD CONSTRAINT "FK_ServiceItem_ServiceItem" FOREIGN KEY ("ServiceItemID") 
REFERENCES "ServiceItem" ("ParentItemID")

如果我删除了外键,一切都按预期工作。这个错误信息令我困惑,我不确定我做错了什么。这是什么意思?

2 个答案:

答案 0 :(得分:2)

我认为应该是相反的方式:

<table name="ServiceItem">
  <column name="ServiceItemID" type="INTEGER" required="true" primaryKey="true"/>
  <column name="ParentItemID"  type="INTEGER" />

  <foreign-key name="FK_ServiceItem_ServiceItem" foreignTable="ServiceItem">
      <reference local="ParentItemID" foreign="ServiceItemID" />
  </foreign-key>
</table>

答案 1 :(得分:1)

在postgresql中,如果要创建外键,则必须遵守以下每条规则:

  1. FOREIGN KEY约束必须引用PRIMARY KEY或UNIQUE约束。
  2. 这两个关键字段必须具有兼容的数据类型。
  3. 必须对引用表和引用表具有REFERENCES权限。
  4. 我碰巧不服从第一个,我指的那个关键并不是唯一的。

    以下是有关如何使用外键的一些有用文档:http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK

    因此,有两种解决方案,要么强制ParentItemID作为唯一列,要么翻转外键,以便主要唯一键成为外部引用。

    我翻转了ParentItemID和ServiceItemID,以便唯一的一个是目标,而非唯一的是受约束的列。

    <table name="ServiceItem">
      <column name="ServiceItemID" type="INTEGER" required="true" primaryKey="true"/>
      <column name="ParentItemID"  type="INTEGER" />
    
      <foreign-key name="FK_ServiceItem_ServiceItem" foreignTable="ServiceItem">
          <reference local="ParentItemID" foreign="ServiceItemID" />
      </foreign-key>
    </table>