多态身份+ history_mapper

时间:2015-07-21 07:43:48

标签: python postgresql sqlalchemy polymorphism

我使用history_meta扩展名(http://docs.sqlalchemy.org/en/latest/_modules/examples/versioned_history/history_meta.html)进行SQLAlchemy。

问题是它似乎不适用于多态身份,至少在使用多个表时如此:

class BaseVersion(Versioned, Base):
    __tablename__ = 'base_version'
    id = Column(Integer, primary_key=True)
    ...
    __mapper_args__ = {
        'polymorphic_identity':'base_version',
        'polymorphic_on':type,
    }

(请注意BaseVersion使用Versioned中定义的history_meta mixin

然后那个类继承自BaseVersion

class UnspecifiedVersion(BaseVersion):
    __tablename__ = 'unspecified_version'
    id = Column(Integer, ForeignKey('base_version.id'), primary_key=True)
    related_base_version_id = Column(Integer, ForeignKey('base_version.id'), index=True)
    related_base_version = relationship('BaseVersion', uselist=False, foreign_keys=[related_base_version_id])
    __mapper_args__ = {
        'polymorphic_identity':'unspecified_version',
        'inherit_condition':(related_base_version_id==BaseVersion.id)
    }

Backend DB是Postgres。

尝试为其生成历史记录表最终会出现错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) there is no unique constraint matching given keys for referenced table "base_version_history"      
 [SQL: '
CREATE TABLE unspecified_version_history (
        id INTEGER NOT NULL,
        related_base_version_id INTEGER,
        version INTEGER NOT NULL,
        changed TIMESTAMP WITHOUT TIME ZONE,
        changed_by VARCHAR,
        PRIMARY KEY (id, version),
        FOREIGN KEY(id, related_base_version_id, version) REFERENCES base_version_history (id, id, version)
)

']

现在这很奇怪,因为base_version_history表肯定有idversion列。

1 个答案:

答案 0 :(得分:0)

我刚刚遇到类似的错误。您的问题似乎是正在生成的复合主键和复合外键,如SQL的最后两行所示:

PRIMARY KEY (id, version),
FOREIGN KEY(id, related_base_version_id, version) REFERENCES base_version_history (id, id, version)

复合外键需要找到匹配的复合唯一键(基本上)。如果此表创建了一个双列主键,则另一个键也可能会执行,并且外键正在查找三列唯一键。此外,同一列两次看起来错误:(id, id, version)。我不知道您正在使用的扩展程序,因此我无法告诉您如何解决它。