我想为异常做一些处理程序。我在python中使用了Flask躁动和SQLAlchemy的组合。
我的问题:
当我用数据库中已经存在的对象向api发送请求时,SQLAlchemy显示异常:
IntegrityError: (IntegrityError) column <column_name> is not unique u'INSERT INTO ...
因此,我尝试将属性validation_exceptions
添加到create_api
方法中:
manager.create_api( ... , validation_exceptions=[IntegrityError])
但响应json包含:
{
"validation_errors": "Could not determine specific validation errors"
}
服务器api显示异常:
Traceback (most recent call last):
File "C:Python27libsite-packagesflask_restlessviews.py", line 797, in _extract_error_messages
left, right = str(exception).rsplit(':', 1)
ValueError: need more than 1 value to unpack
Flask不安中的异常验证不适用于这种类型的异常(IntegrityError)
我该怎么办?有可能为异常创建一些处理程序并用json返回我自己的错误消息吗?
文档(截至本次发布之日的版本0.17.0)指出:
目前,Flask Restless预计指定验证错误的实例将具有errors属性,该属性是将字段名称映射到错误描述的字典(注意:每个字段一个错误)。
因此,要更改validation_errors
的内容,您的异常需要一个包含字典的errors
属性。此字典的内容将作为validation_errors
出现在服务器响应中。
来自烧瓶不稳定/tests/test_validation.py:
class TestSimpleValidation(ManagerTestBase):
"""Tests for validation errors raised by the SQLAlchemy's simple built-in
validation.
For more information about this functionality, see the documentation for
:func:`sqlalchemy.orm.validates`.
"""
def setup(self):
"""Create APIs for the validated models."""
super(TestSimpleValidation, self).setup()
class Person(self.Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
age = Column(Integer, nullable=False)
@validates('age')
def validate_age(self, key, number):
if not 0 <= number <= 150:
exception = CoolValidationError()
exception.errors = dict(age='Must be between 0 and 150')
raise exception
return number
@validates('articles')
def validate_articles(self, key, article):
if article.title is not None and len(article.title) == 0:
exception = CoolValidationError()
exception.errors = {'articles': 'empty title not allowed'}
raise exception
return article
class Article(self.Base):
__tablename__ = 'article'
id = Column(Integer, primary_key=True)
title = Column(Unicode)
author_id = Column(Integer, ForeignKey('person.id'))
author = relationship('Person', backref=backref('articles'))
self.Article = Article
self.Person = Person
self.Base.metadata.create_all()
self.manager.create_api(Article)
self.manager.create_api(Person, methods=['POST', 'PATCH'],
validation_exceptions=[CoolValidationError])
请求:
data = dict(data=dict(type='person', age=-1))
response = self.app.post('/api/person', data=dumps(data))
响应:
HTTP/1.1 400 Bad Request
{ "validation_errors":
{
"age": "Must be between 0 and 150",
}
}
您可以使用预处理器来捕获验证错误。
def validation_preprocessor(data, *args, **kwargs):
# validate data by any of your cool-validation-frameworks
if errors:
raise ProcessingException(description='Something went wrong', code=400)
manager.create_api(
Model,
methods=['POST'],
preprocessors=dict(
POST=[validation_preprocessor]
)
)
但我不确定这是否是一个好方法。