SQLAlchemy - максимальная длина столбца

действительно ли возможно в SQLAlchemy осуществить максимальную длину строки значения, присвоенного отображенному столбцу? Все, что я хочу, должно повысить исключение, если присвоенное строковое значение длиннее затем длина соответствующего столбца таблицы СТРОКИ типа.

Спасибо

6
задан honzas 23 February 2010 в 09:45
поделиться

1 ответ

Проще всего просто переименовать сопоставленный столбец и передать его через свойство:

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 

Вы можете легко исключить создание свойства и даже использовать общую структуру проверки, такую ​​как formencode.


Если вам нужно более специфичное для SQLAlchemy решение и вы не возражаете против использования определенных интерфейсов, тогда SQLAlchemy имеет механизм расширения для захвата событий атрибутов. Валидатор, использующий это, будет выглядеть примерно так:

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

Затем вы можете использовать это расширение, установив __ sa_instrumentation_manager__ = InstallValidatorListeners для любого класса, который вы хотите проверить. Вы также можете просто установить его в базовом классе, если хотите, чтобы он применялся ко всем классам, производным от него.

6
ответ дан 17 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: