5

Mi piacerebbe fare qualche gestore per un'eccezione. Sto usando una combinazione di Flask-irrequiete e SQLAlchemy in python.Come restituire l'errore "esiste già" in Flask-irrequieto?

Il mio problema:

Quando invio richiesta di API con oggetto che esiste già nel DB, SQLAlchemy mostra eccezione:

IntegrityError: (IntegrityError) column <column_name> is not unique u'INSERT INTO ... 

Così ho cercato di aggiungere l'attributo validation_exceptions in create_api metodo:

manager.create_api(... , validation_exceptions=[IntegrityError]) 

Ma la risposta jSON contiene:

{ 
    "validation_errors": "Could not determine specific validation errors" 
} 

e API server mostra eccezione:

Traceback (most recent call last): 
    File "C:\Python27\lib\site-packages\flask_restless\views.py", line 797, in _extract_error_messages 
    left, right = str(exception).rsplit(':', 1) 
ValueError: need more than 1 value to unpack 

convalida delle eccezioni in Flask-inquieta non funziona con questo tipo di eccezione (IntegrityError)

Cosa devo fare? È possibile creare un gestore per eccezione e restituire il mio messaggio di errore in json?

+0

Hai mai capito questo? Stiamo incontrando lo stesso problema. – Mave

+1

No, ho lasciato il pallone immobile per molti altri problemi. Ora sto usando Django Rest Framework –

risposta

0

È possibile utilizzare i preprocessori per l'acquisizione degli errori di convalida.

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] 
    ) 
) 

Ma non sono sicuro che sia un buon modo per farlo.

2

Il documentation (v0.17.0 ad oggi di questo intervento) afferma:

Attualmente, Flask-Restless prevede che l'istanza di un errore di convalida specificato avrà un attributo errori, che è un campo mappatura dizionario nome alla descrizione dell'errore (nota: un errore per campo).

Quindi, per modificare il contenuto del tuo validation_errors eccezione ha bisogno di un attributo errors che contiene un dizionario. Il contenuto di questo dizionario verrà visualizzato nella risposta del server come validation_errors.

Da flask-restless/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]) 

Richiesta:

data = dict(data=dict(type='person', age=-1)) 
response = self.app.post('/api/person', data=dumps(data)) 

Risposta:

HTTP/1.1 400 Bad Request 

{ "validation_errors": 
    { 
     "age": "Must be between 0 and 150", 
    } 
}