Flask SQLAlchemy-使用临时对象更新对象

Flask SQLAlchemy-使用临时对象更新对象,flask,sqlalchemy,marshmallow,Flask,Sqlalchemy,Marshmallow,我正在尝试使用FlaskRESTAPI作为一个简单示例webservice的框架,其中SQLAlchemy作为ORM。除了处理更新外,一切正常 下面是有问题的代码: @blp.arguments(DogSchema) @blp.response(DogSchema) def put(self, data, dog_id): """Update existing dog""" try

我正在尝试使用FlaskRESTAPI作为一个简单示例webservice的框架,其中SQLAlchemy作为ORM。除了处理更新外,一切正常

下面是有问题的代码:

    @blp.arguments(DogSchema)
    @blp.response(DogSchema)
    def put(self, data, dog_id):
        """Update existing dog"""
        try:
            dog = Dog.query.get(dog_id)
        except Exception as e:
            abort(404, message="Item not found - %s" % e)
        
        # update the dog here
        return dog
执行此操作时,
data
变量是一个瞬态狗模型对象。FlaskRESTAPI负责解除JSON请求中数据的序列化,查看棉花糖模式并创建正确类型的sqlalchemy模型对象

为了完整性起见,以下是我的模型和模式:

class Dog(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String, nullable=False)


@api.definition("Dog")
class DogSchema(ma.ModelSchema):
    class Meta:
        model = Dog
        strict = True
        ordered = True
    
    id = field_for(Dog, 'id', dump_only=True)
我想做的就是获取瞬态对象,并使用所有属性更新会话中的对象

我可以用两种不同的方法来做这件事,但我都不喜欢,我希望有更好的方法来做这件事

1) 通过合并 这是可行的,但合并似乎还有其他副作用——如果记录不在会话中,它会从数据库中提取,如果记录不在数据库中,则添加它

2) 通过棉花糖系列化 这使用棉花糖将
数据
变量序列化回JSON,然后重新加载,这似乎效率很低

我真的很想有这么简单的事情

    @blp.arguments(DogSchema)
    @blp.response(DogSchema)
    def put(self, data, dog_id):
        """Update existing dog"""
        try:
            dog = Dog.query.get(dog_id)
        except Exception as e:
            abort(404, message="Item not found - %s" % e)

        dog.update(data)
        db.session.commit()
        return dog
但这似乎不存在,所以希望有人能帮助我


谢谢

您可以为您指定
update
方法
Dog
类:

class Dog(db.Model):
    ...
    def update(self, data):
        for k, v in data.items():
            setattr(self, k, v)
        return self
然后根据需要使用它:

    try:
        dog = Dog.query.get(dog_id)
    except Exception as e:
        abort(404, message="Item not found - %s" % e)

    dog.update(data)
    db.session.commit()

您找到解决方案了吗?
setattr
class Dog(db.Model):
    ...
    def update(self, data):
        for k, v in data.items():
            setattr(self, k, v)
        return self
    try:
        dog = Dog.query.get(dog_id)
    except Exception as e:
        abort(404, message="Item not found - %s" % e)

    dog.update(data)
    db.session.commit()