Sqlalchemy One - 多一合一

nee*_*obe 5 python sqlalchemy

我有两个模型:用户和组。

用户可以在一个组中,因此:

class User(db.Model):
    # other fields
    group_id = db.Column(db.Integer(), db.ForeignKey('group.id'))
Run Code Online (Sandbox Code Playgroud)

但另一方面,我也会有一些有关创建该特定组的用户的信息:

class Group(db.Model):
    # other fields
    users = db.relationship("User", backref='group')
    created_by = db.Column(db.Integer(), db.ForeignKey('user.id'))
Run Code Online (Sandbox Code Playgroud)

结果是:

sqlalchemy.exc.CircularDependencyError: Can't sort tables for DROP; an unresolvable foreign key dependency exists between tables: group, user.  Please ensure that the ForeignKey and ForeignKeyConstraint objects involved in the cycle have names so that they can be dropped using DROP CONSTRAINT.
Run Code Online (Sandbox Code Playgroud)

我试过了use_alter=True,但它给了我:

sqlalchemy.exc.CompileError: Can't emit DROP CONSTRAINT for constraint ForeignKeyConstraint(
Run Code Online (Sandbox Code Playgroud)

Ric*_*Kab 6

有趣的是,我希望你得到一个AmbiguousForeignKeyError,但你似乎得到一个CircularDependencyError?根据文档,这是由两种情况引起的:

  • 在Session刷新操作中,如果两个对象相互依赖,则不能单独通过INSERT或DELETE语句插入或删除它们;需要更新来后关联或预解除关联外键约束值之一。指向自身的行/相互依赖的行中描述的 post_update 标志可以解决此循环。
  • 在MetaData.sorted_tables 操作中,两个ForeignKey 或ForeignKeyConstraint 对象相互引用。将 use_alter=True 标志应用于其中之一或两者,请参阅通过 ALTER 创建/删除外键约束。

我不确定您正在执行的操作导致了此特定错误,但很可能您可以通过解决不明确的引用来解决它。

不明确的引用是由于 SQLAlchemy 无法弄清楚当存在多个引用(本例中为 users 和created_by)时如何执行联接。这可以通过指定关系应如何连接来解决,这可以通过给出应使用的特定外键或显式确定连接条件来完成。

您可以在此处看到这些应用到您的示例中:

class User(Base):
    # Other setup / fields

    group_id = Column(Integer, ForeignKey('group.id'))

class Group(Base):
    # Other setup / fields

    created_by_id = Column(Integer, ForeignKey('user.id'), nullable=False)
    created_by = relationship("User", foreign_keys=[created_by_id])
    users = relationship("User", backref="group", primaryjoin=id==User.group_id)
Run Code Online (Sandbox Code Playgroud)

有关关系连接的文档:http://docs.sqlalchemy.org/en/latest/orm/join_conditions.html#configuring-how-relationship-joins