在SQLAlchemy中使用继承反映PostgreSQL数据库会导致缺少外键关系

时间:2011-07-12 22:42:18

标签: postgresql inheritance sqlalchemy

我在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?或者只是我做了一些根本错误的事情?

1 个答案:

答案 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。所以这里需要触发器来停止更新(更容易)或检查。