Python 更新Flask/SQLAlchemy中的一对多关系
我的数据库中有两个模型父模型和子模型,这两个模型之间存在一对多关系,即一个父模型可以有多个子模型Python 更新Flask/SQLAlchemy中的一对多关系,python,python-3.x,sqlite,flask,sqlalchemy,Python,Python 3.x,Sqlite,Flask,Sqlalchemy,我的数据库中有两个模型父模型和子模型,这两个模型之间存在一对多关系,即一个父模型可以有多个子模型 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 impo
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)
有人能帮我理解我哪里出了问题吗?当我尝试更新父对象而不尝试更新子对象时,更新似乎能按预期工作。只有在我尝试更新子关系时才会出现此问题。尝试将查询从使用
插入到
更改为使用更新
<代码>插入到尝试添加新记录,而更新
将修改现有记录。尝试在ParentResource.put方法中注释掉db.session.add(parent)
。我想你的对象已经在db.session中了,因为你查询了它。我也试过了,得到了同样的错误。它再次尝试执行插入。sqlalchemy.exc.IntegrityError:(sqlite3.IntegrityError)唯一约束失败:parent.name[SQL:INSERT-INTO-parent(name)VALUES(?)]我不是直接运行查询,而是使用ORM,ORM似乎在执行插入而不是奇怪的更新。对,但ORM工具正在幕后执行查询。因此,它可能类似于db.session.update(parent),而不是db.session.add(parent)。
{
"name": "ABCD",
"children": [
"Tom",
"Spot"
]
}