【问题标题】:Self Referential Relationship in SQLAlchemySQLAlchemy 中的自引用关系
【发布时间】:2023-03-17 13:59:01
【问题描述】:

我正在尝试在 SQLAlchemy 中创建自引用关系。

我有一个“问题”类,它可能具有完全相同的“问题”兄弟姐妹,它们完全相同但具有不同的封面图像属性。

如果可能的话,我希望每个模型都包含一个包含其兄弟姐妹列表但不包含自身的属性。

我的问题模型目前如下所示:

class Issue(db.Model):
    __tablename__ = 'issues'
    # IDs
    id = db.Column(db.Integer, primary_key=True)
    title_id = db.Column(db.Integer, db.ForeignKey('titles.id'))
    publisher_id = db.Column(db.Integer, db.ForeignKey('publishers.id'))
    parent_id = db.Column(db.Integer, db.ForeignKey('issues.id'))
    # Attributes
    product_id = db.Column(db.String(100))
    issue_number = db.Column(db.Float)
    .......
    # Relationships
    is_parent = db.Column(db.Boolean(), default=False)
    alternates = db.relationship('Issue',
                backref=db.backref('parent', remote_side=[id])
            )

每个问题都有一个“is_parent”属性,我在确定问题是“基础”问题时设置了该属性。但是,我仍然希望所有兄弟姐妹都能够相互访问。

目前,我正在为“父”问题与其所有“子”/“兄弟”建立关系。

当我与“兄弟”的实例交互时会出现问题。我想直接访问它的所有亲戚,但我必须先通过父母。

任何帮助将不胜感激!

编辑:基本上,我想创建一个自我引用的多对多关系。我认为这是正确的追求方向是错误的吗?

【问题讨论】:

    标签: python sqlalchemy flask flask-sqlalchemy


    【解决方案1】:

    您所做的不是自引用的多对多,而是自引用的一对多(一个父母有很多孩子)。

    首先,您不需要is_parent 布尔值。您可以通过查看 parent_id 字段轻松确定问题是否是父级,该字段仅针对父级指向自身。您可以将以下辅助方法添加到您的 Issue 类:

    def is_parent(self):
        return self.parent_id == self.id
    

    要获取问题的同级,您可以编写一个自定义查询来获取所有具有相同parent_id 的问题,但发出查询的问题除外:

    def get_siblings(self):
        return Issue.query.filter(Issue.parent_id == self.parent_id, Issue.id != self.id).all()
    

    【讨论】:

    • 感谢您提供指导而不是答案。现在我学到了更多关于在 sqlachemy 中进行检查的知识
    【解决方案2】:

    我知道这是旧的,但操作也可以只使用自引用关系方案来轻松找到孩子。以下是在您的小组中的工作方式。

    class Issue(db.Model):
        __tablename__ = 'issues'
        # IDs
        id = db.Column(db.Integer, primary_key=True)
        title_id = db.Column(db.Integer, db.ForeignKey('titles.id'))
        publisher_id = db.Column(db.Integer, db.ForeignKey('publishers.id'))
        parent_id = db.Column(db.Integer, db.ForeignKey('issues.id'))
        # Attributes
        product_id = db.Column(db.String(100))
        issue_number = db.Column(db.Float)
        .......
        # Relationships
        #is_parent = db.Column(db.Boolean(), default=False)
        alternates = db.relationship('Issue',
                    backref=db.backref('parent', remote_side=[id])
                )
        #This is what you need to add to make the database link it self
        parent_id=db.Column(db.Integer, db.ForeignKey('issues.id'))
        children=db.relationship('Issue', backref=db.backref('parent', remote_side=[id]))
    

    给孩子打电话会向您发送父母的所有孩子。调用 parent 将为您提供当前组的父级。如果它返回 None ,那么您正在查看根问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多