Python 如何在SQLAlchemy中设置复杂条件复合外键

Python 如何在SQLAlchemy中设置复杂条件复合外键,python,postgresql,sqlalchemy,declarative,Python,Postgresql,Sqlalchemy,Declarative,这是我的ORM实体类。主键为复合键,因为不同用户的“id_字符串”可能相同(由uid标识)。在基于此类创建表时,我从PostgresSQL错误中了解到一件事( )我需要在父字符串的ForeignKey()参数中添加一些内容。我认为这就是当前记录的uid 您建议尝试使用不同的主键(自动递增整数)还是有其他方法 class SyncEntity(Base): __tablename__ = 'sync_entities' __table_args__ = (ForeignKeyCon

这是我的ORM实体类。主键为复合键,因为不同用户的“id_字符串”可能相同(由uid标识)。在基于此类创建表时,我从PostgresSQL错误中了解到一件事(

)我需要在父字符串的ForeignKey()参数中添加一些内容。我认为这就是当前记录的uid

您建议尝试使用不同的主键(自动递增整数)还是有其他方法

class SyncEntity(Base):
    __tablename__ = 'sync_entities'
    __table_args__ = (ForeignKeyConstraint(['uid'], ['users.uid'], ondelete='CASCADE'), {})

    uid = Column(BigInteger, primary_key=True)

    id_string = Column(String, primary_key=True)
    parent_id_string = Column(String, ForeignKey('sync_entities.id_string'))
    children = relation('SyncEntity',
                        primaryjoin=('sync_entities.c.id_string==sync_entities.c.parent_id_string'),
                        backref=backref('parent', \
                                        remote_side=[id_string]))

    # old_parent_id = ...
    version = Column(BigInteger)
    mtime = Column(BigInteger)
    ctime = Column(BigInteger)
    name = Column(String)
    non_unique_name = Column(String)
    sync_timestamp = Column(BigInteger)
    server_defined_unique_tag = Column(String)
    position_in_parent = Column(BigInteger)

    insert_after_item_id = Column(String, ForeignKey('sync_entities.id_string'))
    insert_after = relation('SyncEntity',
                            primaryjoin=('sync_entities.c.id_string==sync_entities.c.insert_after_item_id'),
                            remote_side=[id_string])

    deleted = Column(Boolean)
    originator_cache_guid = Column(String)
    originator_client_item_id = Column(String)
    specifics = Column(LargeBinary)
    folder = Column(Boolean)
    client_defined_unique_tag = Column(String)
    ordinal_in_parent = Column(LargeBinary)

我想我想出了一个好主意。只需要在\uuuuu tablergs\uuuuuu成员中创建复杂的外键构造,如(parent\u id\u string,uid)和(insert\u after\u item\u id,uid),相应地修改primaryjoin语句。

我想我想出了一个好主意。只需在\uuuu tablergs\uuuuu成员中创建复杂的外键构造,如(parent\u id\u string,uid)和(insert\u after\u item\u id,uid),相应地修改primaryjoin语句。

您知道,主键是一个自动递增的整数通常是最好的方法。任何在系统中看起来是唯一的值,将来可能会被复制。如果你依赖他们的独特性,你就会陷入困境

但是,如果有理由要求每行中的某些值对(或三元组)是唯一的,只需向表中添加约束,但使用自动递增整数作为主键。然后,如果需求发生变化,您可以更改/删除/放松您的独特约束,而无需在其他地方进行更改


另外,如果您使用简单的整数键,那么DBMS可以更快地执行联接。您知道,主键是一个自动递增的整数通常是最好的方法。任何在系统中看起来是唯一的值,将来可能会被复制。如果你依赖他们的独特性,你就会陷入困境

但是,如果有理由要求每行中的某些值对(或三元组)是唯一的,只需向表中添加约束,但使用自动递增整数作为主键。然后,如果需求发生变化,您可以更改/删除/放松您的独特约束,而无需在其他地方进行更改


另外-如果您使用简单的整数键,那么您的联接会更简单,DBMS可以更快地执行。

注意:这是一个非常实用的建议,但也简化了关系模型,其思想是您要深入思考关系行的“标识”是由什么组成的。拥有一个“真正的”复合主键意味着您可以查看另一个表中作为外键出现的键,并实际查看正在发生的事情,而不必追踪键“430021”在主表中引用的内容。此外,如果需求发生变化,您始终可以添加一个自动递增列,并将主键状态传递给它。但后来我开始工作,发现实体是由3-5列标识的,这些列是大整数或varchar,使用它们作为外键需要更新级联触发器,这会降低整个系统的速度。实际上,即使您通过db跟踪对象关系,也更容易在主表中找到它并记下一个键,而不是在每个表有30-60列的几个表中检查5列的值。但要满足您的需要-一如既往:)注意:这是一个非常实用的建议,但也简化了关系模型,即您需要深入思考关系行的“标识”是由什么组成的。拥有一个“真正的”复合主键意味着您可以查看另一个表中作为外键出现的键,并实际查看正在发生的事情,而不必追踪键“430021”在主表中引用的内容。此外,如果需求发生变化,您始终可以添加一个自动递增列,并将主键状态传递给它。但后来我开始工作,发现实体是由3-5列标识的,这些列是大整数或varchar,使用它们作为外键需要更新级联触发器,这会降低整个系统的速度。实际上,即使您通过db跟踪对象关系,也更容易在主表中找到它并记下一个键,而不是在每个表有30-60列的几个表中检查5列的值。但要满足您的需求-一如既往:)
class SyncEntity(Base):
    __tablename__ = 'sync_entities'
    __table_args__ = (ForeignKeyConstraint(['uid'], ['users.uid'], ondelete='CASCADE'), {})

    uid = Column(BigInteger, primary_key=True)

    id_string = Column(String, primary_key=True)
    parent_id_string = Column(String, ForeignKey('sync_entities.id_string'))
    children = relation('SyncEntity',
                        primaryjoin=('sync_entities.c.id_string==sync_entities.c.parent_id_string'),
                        backref=backref('parent', \
                                        remote_side=[id_string]))

    # old_parent_id = ...
    version = Column(BigInteger)
    mtime = Column(BigInteger)
    ctime = Column(BigInteger)
    name = Column(String)
    non_unique_name = Column(String)
    sync_timestamp = Column(BigInteger)
    server_defined_unique_tag = Column(String)
    position_in_parent = Column(BigInteger)

    insert_after_item_id = Column(String, ForeignKey('sync_entities.id_string'))
    insert_after = relation('SyncEntity',
                            primaryjoin=('sync_entities.c.id_string==sync_entities.c.insert_after_item_id'),
                            remote_side=[id_string])

    deleted = Column(Boolean)
    originator_cache_guid = Column(String)
    originator_client_item_id = Column(String)
    specifics = Column(LargeBinary)
    folder = Column(Boolean)
    client_defined_unique_tag = Column(String)
    ordinal_in_parent = Column(LargeBinary)