SQLAlchemy中的自引用关系

时间:2013-09-02 16:20:21

标签: python sqlalchemy flask flask-sqlalchemy

我正在尝试在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'属性,我在确定问题是“基础”问题时设置该属性。但是,我仍然希望所有兄弟姐妹能够互相访问。

目前,我正在向'父母'问题提供与其所有'孩子'/'兄弟姐妹'的关系。

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

非常感谢任何帮助!

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

2 个答案:

答案 0 :(得分:2)

你所做的不是多对多的自我指涉,而是一对一的自我指导(一个父母有很多孩子)。

首先,您不需要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()

答案 1 :(得分:0)

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

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]))

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