Mie*_*iek 4 python postgresql sqlalchemy python-3.x
我使用以下内容在 SQLAlchemy 中创建了多对多关系:
b_c = Table('b_c',
Column('b_id', UUIDType(binary=False), ForeignKey('b.id'), primary_key=True),
Column('c_id', UUIDType(binary=False), ForeignKey('c.id'), primary_key=True)
)
Run Code Online (Sandbox Code Playgroud)
其中c和b是只有一id列 ( UUIDType(binary=false)) 的表以及与此类似的模型:
class A(object):
__tablename__ = 'a'
id = Column('id', UUIDType(binary=False), default=uuid.uuid4, primary_key=True)
class B(object):
__tablename__ = 'b'
id = Column('id', UUIDType(binary=False), default=uuid.uuid4, primary_key=True)
a_id = Column(UUIDType(binary=False), ForeignKey('a.id'), nullable=False)
a = relationship('A')
class C(object):
__tablename__ = 'c'
id = Column('id', UUIDType(binary=False), default=uuid.uuid4, primary_key=True)
a_id = Column(UUIDType(binary=False), ForeignKey('a.id'), nullable=False)
a = relationship('A')
Run Code Online (Sandbox Code Playgroud)
这种关系工作得非常好,我能够根据我的使用场景将 B 和 C 对象过滤到父 A。但是,为了确保超出使用这些模型的逻辑的数据的完整性,是否有任何最佳实践要求对于任何关系b_c, b.amust equal c.a?
抱歉,如果这是其他答案,但我发现的任何示例都是针对表本身值的简单 CHECK 约束,并且不需要连接表的值。
从文档:
目前,CHECK 表达式不能包含子查询,也不能引用当前行列以外的变量。可以引用系统列 tableoid,但不能引用任何其他系统列。
您所描述的内容无法通过检查约束完成,但可以在插入或更新之前通过 sql 触发器实现:
这是一个 postgresql 函数和触发器定义,用于检查引用表的a_id外键是否相等。
CREATE FUNCTION ckref_b_c() RETURNS trigger AS $ckref_b_c$
DECLARE
bid uuid;
cid uuid;
BEGIN
select a_id INTO bid FROM b WHERE id = NEW.b_id;
select a_id INTO cid FROM c WHERE id = NEW.c_id;
IF bid != cid THEN
RAISE EXCEPTION 'associated records do not refer to same parent in `a`';
END IF;
RETURN NEW;
END;
$ckref_b_c$ LANGUAGE plpgsql;
CREATE TRIGGER ckref_b_c BEFORE INSERT OR UPDATE ON b_c
FOR EACH ROW EXECUTE PROCEDURE ckref_b_c();
Run Code Online (Sandbox Code Playgroud)
创建表后,您可以通过 sqlalchemy 引擎执行这些查询。Sqlalchemy 也有一个事件系统,您可以使用它来自动发出这些查询。
| 归档时间: |
|
| 查看次数: |
833 次 |
| 最近记录: |