Отношение один ко многим - PullRequest
0 голосов
/ 18 мая 2019

Я довольно новичок в питоне (меньше чем за день!).Я пытаюсь создать Restful API с помощью Flask.У меня есть класс class TaskModel(db.Model):, который имеет отношение к задаче.На самом деле, у задачи может быть много предшественников (в зависимости от поля).

Но когда я добавляю отношение ниже, я получаю эту ошибку: 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)

Заранее спасибо :)

1 Ответ

0 голосов
/ 19 мая 2019

В 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 и дочерним элементам, это сочетание двух дастВы, что вам нужно, самоотношения по задачам, по базе данных parent_id будет добавлен к вашей таблице.

...