![](/img/trans.png)
[英]PostgreSQL psycopg2 error: there is no unique constraint / InvalidForeignKey
[英]postgresql no unique constraint error
我为这个模式得到这个错误:
ERROR: there is no unique constraint matching given keys for referenced table "abteilung"
我做错了什么? 编辑:现在我将列krankenhaus添加到表mitarbeiter并更改alter table命令,但是我得到相同的错误...
模式:
CREATE TABLE Person (
svnr VARCHAR(40) PRIMARY KEY,
anschrift VARCHAR(40) NOT NULL,
name VARCHAR(20) NOT NULL
);
BEGIN;
CREATE TABLE Mitarbeiter (
svnr VARCHAR(40) PRIMARY KEY REFERENCES Person(svnr),
beschaeftigt_seit DATE NOT NULL,
gehalt NUMERIC(5,2),
CHECK(gehalt > 0),
abteilung INTEGER NOT NULL,
krankenhaus INTEGER NOT NULL
);
CREATE TABLE Krankenhaus (
kid INTEGER PRIMARY KEY DEFAULT nextval('seq_krankenhaus'),
anschrift VARCHAR(40) NOT NULL,
name VARCHAR(20) NOT NULL,
geleitet_von VARCHAR(40) REFERENCES Mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
);
CREATE TABLE Abteilung (
abid INTEGER DEFAULT nextval('seq_abteilung'),
name VARCHAR(40) NOT NULL,
anschrift VARCHAR(40) NOT NULL,
koordiniert VARCHAR(40) REFERENCES Mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED,
krankenhaus INTEGER REFERENCES Krankenhaus(kid),
PRIMARY KEY (abid, krankenhaus)
);
ALTER TABLE Mitarbeiter ADD CONSTRAINT fk_abteilung FOREIGN KEY (abteilung, krankenhaus) REFERENCES Abteilung(abid, krankenhaus) DEFERRABLE INITIALLY DEFERRED;
COMMIT;
表Abteilung
的主键是(abid, krankenhaus)
。 由于外部引用仅引用一行,因此您还需要在外键约束定义中同时使用两列。
但是当你没有列krankenhaus
在你的表Mitarbeiter
你不能引用Abteilung
。
您或者需要将Abteilung
的主键减小为(abid)
(因为无论如何它都是生成的人工键,这都是可能的),或者在Mitarbeiter
表中添加一列Krankenhaus
。
这应该工作:
CREATE TABLE person (
svnr text PRIMARY KEY
, anschrift text NOT NULL
, name text NOT NULL
);
CREATE TABLE mitarbeiter (
svnr text PRIMARY KEY REFERENCES person
, beschaeftigt_seit date NOT NULL
, gehalt numeric(5,2)
, abid int NOT NULL
, CHECK(gehalt > 0)
);
CREATE TABLE krankenhaus (
kid serial PRIMARY KEY
, anschrift text NOT NULL
, name text NOT NULL
, geleitet_von text REFERENCES mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
);
CREATE TABLE abteilung (
abid serial PRIMARY KEY
, kid INTEGER REFERENCES krankenhaus(kid)
, koordiniert text REFERENCES mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
, name text NOT NULL
, anschrift text NOT NULL
);
ALTER TABLE mitarbeiter
ADD CONSTRAINT fk_abteilung FOREIGN KEY (abid)
REFERENCES abteilung(abid) DEFERRABLE INITIALLY DEFERRED;
将serial
列用于替代PK:
请勿对字符串长度使用具有任意限制的varchar(n)
,除非您确实需要强制执行最大长度且该长度不会改变。 细节:
一起去的只是abid
作为主键abteilung
。 有将是包含在FK约束冗余列相关的应用程序,但是这是你的模型确实现在不是:
无需为部分代码使用显式事务( BEGIN ... COMMIT
)。
这种循环引用的真正困难在于输入和更改数据。 您可能使FK约束DEFERRABLE INITIALLY DEFERRED
-这将使某些查询变得相当慢 。
如果将相关行上的INSERT / UPDATE包装到可修改数据的CTE中 ,则可以使用普通的默认IMMEDIATE
FK约束:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.