SQLAlchemy non crea questo in quanto rimanda al DBAPI/database come la migliore e più efficiente fonte di convalida e coercizione dei valori.
Per creare la propria convalida, viene utilizzata la convalida di tipo TypeDecorator o ORM. TypeDecorator ha il vantaggio che opera nel core e può essere piuttosto trasparente, anche se si verifica solo quando SQL viene effettivamente emesso.
Per eseguire la convalida e la coercizione prima, questo è al livello ORM.
validazione può essere ad hoc, in corrispondenza dello strato ORM, via @validates
:
http://docs.sqlalchemy.org/en/latest/orm/mapped_attributes.html#simple-validators
Il sistema di eventi che @validates usi è disponibile anche direttamente. È possibile scrivere una soluzione generalizzata che collega validatori di tua scelta per i tipi di essere mappati:
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import event
import datetime
Base= declarative_base()
def validate_int(value):
if isinstance(value, basestring):
value = int(value)
else:
assert isinstance(value, int)
return value
def validate_string(value):
assert isinstance(value, basestring)
return value
def validate_datetime(value):
assert isinstance(value, datetime.datetime)
return value
validators = {
Integer:validate_int,
String:validate_string,
DateTime:validate_datetime,
}
# this event is called whenever an attribute
# on a class is instrumented
@event.listens_for(Base, 'attribute_instrument')
def configure_listener(class_, key, inst):
if not hasattr(inst.property, 'columns'):
return
# this event is called whenever a "set"
# occurs on that instrumented attribute
@event.listens_for(inst, "set", retval=True)
def set_(instance, value, oldvalue, initiator):
validator = validators.get(inst.property.columns[0].type.__class__)
if validator:
return validator(value)
else:
return value
class MyObject(Base):
__tablename__ = 'mytable'
id = Column(Integer, primary_key=True)
svalue = Column(String)
ivalue = Column(Integer)
dvalue = Column(DateTime)
m = MyObject()
m.svalue = "ASdf"
m.ivalue = "45"
m.dvalue = "not a date"
convalida e la coercizione può anche essere costruito a livello di tipo utilizzando TypeDecorator, anche se questo è solo quando viene emesso SQL, come ad come questo esempio che converte stringhe UTF-8 a Unicode:
http://docs.sqlalchemy.org/en/latest/core/custom_types.html#coercing-encoded-strings-to-unicode
Eventuali duplicati: http://stackoverflow.com/questions/2390753/is-there-a-way-to-transparently-perform-validation -on-sqlalchemy-objects – greut
@greut Non avevo ancora visto questa domanda in precedenza, ma la risposta con il punteggio più alto utilizza un valore deprecato d tecnica. L'altra risposta data è filosofica. Qui abbiamo l'autore di SQLAlchemy con una risposta precisa e utile. – Nate