我在PostgreSQL中创建了一个数据库(8.4 - 我需要使用这个版本,因为我想使用不支持9.0的MapFish),它有一些继承的表:
CREATE TABLE stakeholder
(
pk_stakeholder integer DEFAULT nextval('stakeholder_seq') NOT NULL,
fk_stakeholder_type integer NOT NULL,
name character varying(255) NOT NULL,
CONSTRAINT stakeholder_primarykey PRIMARY KEY (pk_stakeholder),
CONSTRAINT stakeholder_fk_stakeholder_type FOREIGN KEY (fk_stakeholder_type)
REFERENCES stakeholder_type (pk_stakeholder_type) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION
);
CREATE TABLE individual
(
firstname character varying(50),
fk_title integer,
email1 character varying (100),
email2 character varying (100),
phone1 character varying (50),
phone2 character varying (50),
CONSTRAINT individual_primarykey PRIMARY KEY (pk_stakeholder),
CONSTRAINT individual_fk_title FOREIGN KEY (fk_title)
REFERENCES individual_title (pk_individual_title) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION
) INHERITS (stakeholder)
(从earlier question了解到,我正在使用一个单独的表(stakeholder_pk)来使用触发器跟踪我的主键)
现在我想在SQLAlchemy(0.7.1)中反映我的数据库:
meta.metadata.reflect(bind=engine)
table_stakeholder = meta.metadata.tables["stakeholder"]
table_individual = meta.metadata.tables["individual"]
stakeholder_mapper = orm.mapper(Stakeholder, table_stakeholder,
polymorphic_on=table_stakeholder.c.fk_stakeholder_type,
polymorphic_identity='stakeholder')
orm.mapper(Individual, table_individual, inherits=stakeholder_mapper,
polymorphic_identity='individual')
然而,这导致了sqlalchemy.exc.ArgumentError:找不到“利益相关者”和“个人”之间的任何外键关系。
现在我已经看到一些例子,他们使用子表的主键(在我的情况下:个人)作为指向父表(利益相关者)主键的外键。但是,PostgreSQL不允许我这样做,说这会违反外键约束,因为父表(利益相关者)中的主键不存在(?)。
所以现在我几乎陷入困境,经过数小时寻找解决方案后,我开始失去对它的追踪。这是PostgreSQL中的问题(类似于主键和继承问题)还是因为SQLAlchemy?或者只是我做了一些根本错误的事情?
答案 0 :(得分:1)
在PostgreSQL中:
父表上的所有检查约束和非空约束都由其子表自动继承。其他类型的约束(唯一,主键和外键约束)不会被继承。
这些缺陷可能会在未来的某个版本中修复,但同时需要非常谨慎地决定继承是否对您的应用程序有用。
http://www.postgresql.org/docs/9.0/interactive/ddl-inherit.html
是否可以放弃触发器并拥有个体:
pk_stakeholder integer DEFAULT nextval('stakeholder_seq') NOT NULL,
...
CONSTRAINT stakeholder_primarykey PRIMARY KEY (pk_stakeholder),
如果您稍后更新pk_stakeholder,这不会阻止个人拥有利益相关者中存在的pk_stakeholder。所以这里需要触发器来停止更新(更容易)或检查。