【问题标题】:One to Many Self-Referencing relation SQLAlchemy一对多自引用关系 SQLAlchemy
【发布时间】:2019-05-18 20:08:33
【问题描述】:

我是 python 的新手(不到一天!)。 我正在尝试使用 Flask 构建一个 Restful API。我有类class TaskModel(db.Model):,它与任务有自引用关系。 实际上,一个任务可以有多个前置任务(dependsOn 字段)。

但是当我添加下面的关系时,我得到了这个错误: sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship TaskModel.dependsOn - there are no foreign keys linking these tables.

我的整个任务类如下:

class TaskModel(db.Model):
    """
    Task Model
    """

    # table name
    __tablename__ = 'tasks'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False)
    department = db.Column(db.String(128), nullable=False)
    earliestStart = db.Column(db.String(10), nullable=False)
    latestEnd = db.Column(db.String(10), nullable=False)
    duration = db.Column(db.String(10), nullable=False)
    dnetworkId = db.Column(db.Integer, db.ForeignKey('dnetworks.id'), nullable=False)
    dependsOn = db.relationship('TaskModel', backref='tasks',remote_side=[id], lazy=True)


....

class TaskSchema(Schema):
    """
    Task Schema
    """
    id = fields.Int(dump_only=True)
    name = fields.Str(required=True)
    department = fields.Str(required=True)
    earliestStart = fields.Str(required=True)
    latestEnd = fields.Str(required=True)
    dnetworkId = fields.Int(required=True)
    duration = fields.Str(required=True)
    dependsOn = fields.Nested('self', many=True, exclude=('dependsOn',))
    # dependsOn = fields.Nested('self', exclude=('dependsOn',), default=None, many=True)

提前谢谢:)

【问题讨论】:

    标签: python sql flask one-to-many


    【解决方案1】:

    在关系的 SqlAlchemy 中,您应该定义两种方式,以下是您可能正在寻找的完整工作示例:

    import os
    from sqlalchemy.orm import relationship, backref
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    app = Flask(__name__)
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////{}/my.db'.format(BASE_DIR)
    
    db = SQLAlchemy(app)
    
    
    class TaskModel(db.Model):
        __tablename__ = 'tasks'
    
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(128), nullable=True)
        parent_id =  db.Column(db.Integer, db.ForeignKey("tasks.id"))
        children = relationship("TaskModel",
            backref=backref('parent', remote_side=[id])
        )
    
    
    if __name__ == "__main__":
        db.create_all()
        tm = TaskModel(name='Test1')
        db.session.add(tm)
        db.session.commit()
    

    注意 parent_id 和 children,这两者的组合会给你你需要的东西,任务的自我关系,数据库上的 parent_id 将被添加到你的表中。

    【讨论】:

    • 感谢您的回答,但我有一个问题。在那种情况下,一个任务可以有很多依赖任务吗?
    • 这是一个树结构和一对多,意思是一个父任务下可以有多个子任务,如果需要多对多(不是树,就是图) 那么这是一个不同的故事,根据我所看到的,树应该没问题。
    • 但正如我在您的代码中看到的那样,每个任务都可以有一个父级(取决于)。但就我而言,我希望有多个dependsOn。
    • dependsOn 将是孩子们,试试吧
    猜你喜欢
    • 1970-01-01
    • 2018-10-02
    • 2011-05-09
    • 2021-05-31
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 2021-08-31
    相关资源
    最近更新 更多