我正在尝试使用flask-rest-api作为带有SQLAlchemy作为ORM的简单示例Web服务的框架。一切正常,除了处理更新。
这是有问题的代码:
@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
变量是一个瞬时Dog模型对象。 flask-rest-api负责反序列化JSON请求中的数据,查看您的棉花糖模式并创建正确类型的sqlalchemy Model对象。
出于完整性考虑,这是我的模型和架构:
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)
我想做的就是获取临时对象,并在会话中使用所有属性更新对象。
我已经能够通过两种不同的方式来做到这一点,我都不喜欢,而且我希望有一种更好的方式来做到这一点。
@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)
data.id = dog_id
db.session.merge(data)
db.session.commit()
return dog
这有效,但是合并似乎还有其他副作用-如果记录不在会话中,它将从数据库中拉出;如果数据库中不存在该记录,则将其添加。
@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)
serializer = DogSchema()
serializer.load(serializer.dump(data).data, instance=dog, session=db.session, partial=True)
db.session.commit()
return dog
这使用棉花糖将data
变量序列化回JSON,然后再将其加载回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
但这似乎不存在,所以希望有人可以帮助我。
谢谢!
答案 0 :(得分:0)
您可以为update
类指定Dog
方法:
class Dog(db.Model):
...
def update(self, data):
for k, v in data.items():
settatr(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()