phi*_*ee2 6 python database orm sqlalchemy
我正在尝试在插入或更新之前验证 SQLAlchemy 模型,例如
class MyModel(db.Model):
foo = db.Column(db.String(255))
bar = db.Column(db.String(255))
Run Code Online (Sandbox Code Playgroud)
我尝试了几种方法,但似乎都不起作用。一种可能性是监听before_insert和before_update事件,例如
@event.listens_for(MyModel, 'before_insert')
@event.listens_for(MyModel, 'before_update')
def validate_my_model(mapper, connection, model):
if not is_valid(model):
raise Exception("the model isn't valid")
Run Code Online (Sandbox Code Playgroud)
这工作正常,但在测试中我会收到此错误,除非我回滚会话。
This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback()
Run Code Online (Sandbox Code Playgroud)
我可以调用session.rollback()测试,但我这似乎不正确,因为测试只是发出 PUT/POST 请求,不应该真正了解会话或任何 SQLAlchemy 内部结构。
另一种选择是监听init事件,而不是before_insertand before_update,但这不处理更新情况。
我也尝试使用@validates,例如
@validates('foo', 'bar')
def validate(self, key, val):
...
Run Code Online (Sandbox Code Playgroud)
但是,验证依赖于这两个属性,而validate为每个属性单独调用该方法。这意味着,如果我尝试在模型上同时设置foo和bar,它会尝试验证一个属性已设置但另一个尚未设置的中间状态。
尝试flask-marshmallowmarshmallow_sqlalchemy,它基于marshmallow验证包。它允许您根据数据库模型进行验证。创建架构文件
import MyModel
import db
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
class MyModelSchema(SQLAlchemyAutoSchema):
class Meta:
sqla_session = Session
load_instance = True
model = MyModel
Run Code Online (Sandbox Code Playgroud)
model在类内部添加Meta将有助于根据模型进行验证,并load_instance让我们将对象作为模型实例加载到 API 中
from schemas import MyModelSchema
model_schema = MyModelSchema()
# API post route
def post(self):
model_json = request.get_json()
model = model_schema.load(model_json)
db.session(model)
db.session.commit()
return {"message": "model created"}, 201
Run Code Online (Sandbox Code Playgroud)
最后向 Flask 应用程序内的用户 marshmallow 发送,如果发送的正文未经过验证,则返回验证错误消息,在应用程序根文件中添加
from flask_marshmallow import Marshmallow
from marshmallow import ValidationError
# marshmallow config
ma = Marshmallow(app)
# marshamallow global exception handler
@app.errorhandler(ValidationError)
def handle_marshmallow_validation(err):
return jsonify(err.messages), 400
Run Code Online (Sandbox Code Playgroud)
希望这个对你有帮助。