2010-02-23 32 views
6

SQLAlchemy'de eşlenen sütuna atanan değerin maksimum dize uzunluğunu zorlamak mümkün mü? Tek istediğim, atanmış bir dize değeri daha uzunsa, STRING türünde karşılık gelen tablo sütununun uzunluğunun bir istisna oluşturmasıdır.SQLAlchemy - maksimum sütun uzunluğu

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 

kolaylıkla mülk oluşturma faktörü dışında ve hatta formencode gibi genel bir doğrulama çerçevesi kullanabilirsiniz:

Sadece bir özelliği üzerinden eşlenen sütun ve vekil yeniden adlandırmak en kolay

+0

masayı ve sınıfına eşleme tanımlamak için kullandığınız kodunu belirtin: Burada –

+0

@ S.Lott MySQL, insert/update üzerindeki string uzunluğunu kontrol etmez. Çok uzun olan dizeleri sessizce keser. – codeape

cevap

6

teşekkür ederiz . Eğer daha SQLAlchemy belirli bir çözüm gerek ve spesifik arayüzlerini kullanarak sakıncası yoksa


ardından SQLAlchemy niteliklerini olayları yakalamak için bir uzatma mekanizması vardır. o kullanan bir doğrulayıcı şöyle görünecektir:

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 

Daha sonra valide istediğiniz sınıfın üzerine __sa_instrumentation_manager__ = InstallValidatorListeners ayarlayarak bu uzantıyı kullanmak. Ayrıca, ondan türetilen tüm sınıflara uygulanmasını istiyorsanız, bunu Temel sınıfta da ayarlayabilirsiniz.

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 
+0

Evet, bu sorunu çözüyor, ancak bu tür sütunlar onlarca var, bu yüzden özelliği kullanmak çok uygun değil. SQLAlchemy tipi sistemi kullanan çözüm daha iyi olurdu. – honzas

+0

Ben sqlichemy özgü validators için kullanılabilecek bir örnek ekledim. –

+0

Evet, bu tür bir çözüm benim için ideal, teşekkürler. – honzas

0

yeni sqlalchemy versiyonlarının olay sistemini uyan güncelleştirilmiş bir sürümüdür. AFAIK, veritabanı SQLAlchemy üzerinden geri yayılan bir hata ortaya çıkarmalıdır. Şimdi ne denediğinize dair ipucu vermek için lütfen kod gönderin.
İlgili konular