簡體   English   中英

更新 Flask/SQLAlchemy 中的一對多關系

[英]Updating one to many relationship in Flask/ SQLAlchemy

我的數據庫中有兩個模型 Parent 和 Child,這兩個模型之間存在一對多的關系,即一個父母可以有多個孩子。

from flask import Flask, request
from flask_restful import Resource
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_restful import Api
from marshmallow import fields

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///relationships.db"
db = SQLAlchemy(app)
ma = Marshmallow(app)
api = Api(app, prefix="/api")


class Parent(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), nullable=False, unique=True)
    children = db.relationship("Child", backref="parent")


class Child(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), nullable=False, unique=True)
    parent_id = db.Column(db.Integer, db.ForeignKey("parent.id"))


class ChildSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Child
        ordered = True
        include_fk = True
        dump_only = ("id",)
        load_instance = True


class ParentSchema(ma.SQLAlchemyAutoSchema):
    children = fields.Pluck(ChildSchema, "name", many=True)

    class Meta:
        model = Parent
        ordered = True
        include_relationships = True
        dump_only = ("id",)
        load_instance = True

class ParentResource(Resource):
    @classmethod
    def get(cls, _id: int):
        parent_schema = ParentSchema()
        return parent_schema.dump(parent.query.filter_by(id=_id).first()), 200

    @classmethod
    def put(cls, _id: int):
        parent_json = request.get_json()
        parent_schema = ParentSchema()

        parent_input_data = parent_schema.load(parent_json)

        parent = Parent.query.filter_by(id=_id).first()
        parent.name = parent_input_data.name

        child_names = [child.name.lower() for child in parent.children]

        # Check if child is not already in parent children list
        for child_input in parent_input_data.children:
            if child_input.name.lower() not in child_names:
                parent.children.append(child_input)

        db.session.add(parent)
        db.session.commit()

        return {"message": "Updated"}, 200


api.add_resource(ParentResource, "/parent/<int:_id>")

if __name__ == "__main__":
    db.create_all()
    app.logger.info("Starting app...")
    app.run("127.0.0.1", 3003)

當我嘗試通過添加一些新子項來更新父項時,我收到一個唯一鍵約束錯誤,因為 SQLAlchemy 似乎正在嘗試在父表中運行插入查詢,而不是嘗試更新父表記錄。 父表中已經有一條同名“ABCD”的記錄,即我只是嘗試保持父名稱不變並更新子表。

在此處輸入圖像描述

這是我給 PUT 請求的輸入。

{
    "name": "ABCD",
    "children": [
        "Tom",
        "Spot"
    ]
}

有人可以幫我理解我哪里出錯了嗎? 當我嘗試更新父級而不嘗試更新子級時,更新似乎按預期工作。 僅當我嘗試更新子關系時才會出現此問題。

嘗試將您的查詢從使用INSERT INTO更改為使用UPDATE INSERT INTO嘗試添加新記錄,而UPDATE將修改現有記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM