SQLAlchemy không xây dựng điều này vì nó bảo vệ DBAPI/cơ sở dữ liệu là nguồn xác thực và ép buộc hiệu quả nhất và hiệu quả nhất.
Để xây dựng xác thực của riêng bạn, thường sử dụng xác thực cấp độ xác thực hoặc xác thực cấp ORM. TypeDecorator có lợi thế là nó hoạt động ở lõi và có thể khá trong suốt, mặc dù nó chỉ xảy ra khi SQL thực sự được phát ra.
Để thực hiện xác thực và cưỡng chế sớm hơn, điều này ở cấp ORM.
Validation có thể ad-hoc, ở lớp ORM, qua @validates
:
http://docs.sqlalchemy.org/en/latest/orm/mapped_attributes.html#simple-validators
Hệ thống sự kiện rằng @validates sử dụng cũng có sẵn trực tiếp. Bạn có thể viết một giải pháp tổng quát liên kết xác nhận lựa chọn của bạn cho các loại được ánh xạ:
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"
Validation và ép buộc cũng có thể được xây dựng ở cấp loại sử dụng TypeDecorator, mặc dù điều này chỉ là khi SQL đang được phát ra, chẳng hạn như ví dụ này mà cưỡng ép utf-8 chuỗi để unicode:
http://docs.sqlalchemy.org/en/latest/core/custom_types.html#coercing-encoded-strings-to-unicode
có thể trùng lặp: http://stackoverflow.com/questions/2390753/is-there-a-way-to-transparently-perform-validation -on-sqlalchemy-objects – greut
@greut Tôi chưa từng thấy câu hỏi đó trước đó, nhưng câu trả lời được đánh giá cao nhất sử dụng một sự phản đối d kỹ thuật. Câu trả lời khác được đưa ra là câu trả lời triết học. Ở đây chúng ta có tác giả của SQLAlchemy với một câu trả lời chính xác và hữu ích. – Nate