2010-02-23 39 views
6

là có thể trong SQLAlchemy để thực thi độ dài chuỗi tối đa của giá trị được gán cho cột được ánh xạ không? Tất cả những gì tôi muốn là tăng ngoại lệ nếu giá trị chuỗi được chỉ định dài hơn độ dài của cột bảng tương ứng thuộc loại STRING.SQLAlchemy - chiều dài cột tối đa

Cảm ơn bạn

+0

Vui lòng cung cấp mã bạn đang sử dụng để xác định các bảng và các bản đồ để lớp học của bạn. AFAIK, cơ sở dữ liệu nên nêu ra một lỗi truyền lại thông qua SQLAlchemy. Vui lòng đăng mã để cung cấp một số gợi ý về những gì bạn đang cố gắng ngay bây giờ. –

+0

@ S.Lott MySQL không kiểm tra độ dài chuỗi khi chèn/cập nhật. Nó âm thầm cắt ngắn các chuỗi quá dài. – codeape

Trả lời

6

Đó là đơn giản nhất để chỉ đổi tên các cột ánh xạ và proxy nó thông qua một tài sản:

class Something(Base): 
    ... 
    _foo = Column('foo', String(123)) 

    @property 
    def foo(self): 
     return self._foo 

    @foo.setter 
    def foo(self, value): 
     if len(value) > _foo.type.length: 
      raise Exception("Value too long") 
     self._foo = value 

Bạn có thể dễ dàng yếu tố ra việc tạo ra tài sản, và thậm chí sử dụng một khuôn khổ xác nhận chung chung như formencode .


Nếu bạn cần thêm giải pháp SQLAlchemy cụ thể và không ngại sử dụng giao diện cụ thể, thì SQLAlchemy có cơ chế mở rộng để ghi lại sự kiện trên thuộc tính. Một validator sử dụng đó sẽ giống như thế này:

from sqlalchemy.orm.interfaces import AttributeExtension, InstrumentationManager 
from sqlalchemy.orm import ColumnProperty 

class InstallValidatorListeners(InstrumentationManager): 
    def post_configure_attribute(self, class_, key, inst): 
     """Add validators for any attributes that can be validated.""" 
     prop = inst.prop 
     # Only interested in simple columns, not relations 
     if isinstance(prop, ColumnProperty) and len(prop.columns) == 1: 
      col = prop.columns[0] 
      # if we have string column with a length, install a length validator 
      if isinstance(col.type, String) and col.type.length: 
       inst.impl.extensions.insert(0, LengthValidator(col.type.length)) 

class ValidationError(Exception): 
    pass 

class LengthValidator(AttributeExtension): 
    def __init__(self, max_length): 
     self.max_length = max_length 

    def set(self, state, value, oldvalue, initiator): 
     if len(value) > self.max_length: 
      raise ValidationError("Length %d exceeds allowed %d" % 
           (len(value), self.max_length)) 
     return value 

Sau đó bạn sẽ sử dụng tiện ích này bằng cách thiết lập __sa_instrumentation_manager__ = InstallValidatorListeners trên bất kỳ lớp học mà bạn muốn xác nhận. Bạn cũng có thể đặt nó trên lớp cơ sở nếu bạn muốn nó áp dụng cho tất cả các lớp bắt nguồn từ nó.

+0

Có, nó giải quyết được vấn đề, nhưng tôi có hàng chục cột như vậy, vì vậy việc sử dụng tài sản không thuận tiện lắm. Giải pháp sử dụng hệ thống kiểu SQLAlchemy sẽ tốt hơn. – honzas

+0

Tôi đã thêm một ví dụ có thể được sử dụng cho các trình xác thực cụ thể sqlalchemy. –

+0

Vâng, loại giải pháp này lý tưởng cho tôi, cảm ơn bạn. – honzas

0

Dưới đây là một phiên bản cập nhật phù hợp với hệ thống sự kiện của phiên bản SQLAlchemy mới hơn:

class InstallValidatorListeners(InstrumentationManager): 
    def post_configure_attribute(self, class_, key, inst): 
     """Add validators for any attributes that can be validated.""" 
     prop = inst.prop 
     # Only interested in simple columns, not relations 
     if isinstance(prop, ColumnProperty) and len(prop.columns) == 1: 
      col = prop.columns[0] 
      if isinstance(col.type, String) and col.type.length: 
       sqlalchemy.event.listen(
        getattr(class_, key), 'set', LengthValidator(col.type.length), retval=True) 


class ValidationError(Exception): 
    pass 


class LengthValidator(AttributeExtension): 
    def __init__(self, max_length): 
     self.max_length = max_length 

    def __call__(self, state, value, oldvalue, initiator): 
     if len(value) > self.max_length: 
      raise ValidationError(
       "Length %d exceeds allowed %d" % (len(value), self.max_length)) 
     return value 
Các vấn đề liên quan