Есть ли способ прозрачно выполнить проверку на объектах SQLAlchemy?

Есть ли способ выполнить проверку объекта после (или как) свойств, установленных до начала сеанса?

Например, у меня есть устройство модели домена, обладающее свойством mac . Я хотел бы убедиться, что свойство mac содержит действительное и дезинфицированное значение mac перед его добавлением или обновлением в базе данных.

Похоже, что подход Pythonic – это делать большинство вещей как свойств (включая SQLAlchemy). Если бы я закодировал это на PHP или Java, я бы, вероятно, решил создать методы getter / setter для защиты данных и дать мне возможность справиться с этим в самой модели домена.

 public function mac() { return $this->mac; } public function setMac($mac) { return $this->mac = $this->sanitizeAndValidateMac($mac); } public function sanitizeAndValidateMac($mac) { if ( ! preg_match(self::$VALID_MAC_REGEX) ) { throw new InvalidMacException($mac); } return strtolower($mac); } 

Что такое Pythonic способ справиться с этим типом ситуации с помощью SQLAlchemy?

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

ОБНОВИТЬ

Я знаю, что я могу использовать свойство, чтобы делать это при обычных обстоятельствах. Ключевой частью является то, что я использую SQLAlchemy с этими классами. Я не совсем понимаю, как SQLAlchemy выполняет свою магию, но я подозреваю, что создание и переопределение этих свойств на мой взгляд может привести к нестабильным и / или непредсказуемым результатам.

  • Как запросить для всех групп типа 'foo', которые содержат user_x? (таблица «многие-ко-многим»)
  • SQLAlchemy DELETE Ошибка, вызванная наличием как ленивой нагрузки, так и динамической версии того же отношения
  • sqlalchemy - элегантный способ борьбы с несколькими дополнительными фильтрами?
  • Python прописывает в sqlalchemy
  • Как сделать соединение mysql, требующее CA-CERT с sqlalchemy или SQLObject
  • Создайте динамическую форму, используя флягу-wtf и sqlalchemy
  • pip install -upgrade sqlalchemy дает максимальную глубину рекурсии
  • Использование cdecimal в SQLAlchemy
  • 3 Solutions collect form web for “Есть ли способ прозрачно выполнить проверку на объектах SQLAlchemy?”

    Вы можете добавить проверку данных внутри своих классов SQLAlchemy с помощью декоратора @validates() .

    Из документов – Простые валидаторы :

    Валидатор атрибутов может вызывать исключение, останавливать процесс изменения значения атрибута или изменять данное значение во что-то другое.

     from sqlalchemy.orm import validates class EmailAddress(Base): __tablename__ = 'address' id = Column(Integer, primary_key=True) email = Column(String) @validates('email') def validate_email(self, key, address): # you can use assertions, such as # assert '@' in address # or raise an exception: if '@' not in address: raise ValueError('Email address must contain an @ sign.') return address 

    Да. Это можно сделать с помощью MapperExtension.

     # uses sqlalchemy hooks to data model class specific validators before update and insert class ValidationExtension( sqlalchemy.orm.interfaces.MapperExtension ): def before_update(self, mapper, connection, instance): """not every instance here is actually updated to the db, see http://www.sqlalchemy.org/docs/reference/orm/interfaces.html?highlight=mapperextension#sqlalchemy.orm.interfaces.MapperExtension.before_update""" instance.validate() return sqlalchemy.orm.interfaces.MapperExtension.before_update(self, mapper, connection, instance) def before_insert(self, mapper, connection, instance): instance.validate() return sqlalchemy.orm.interfaces.MapperExtension.before_insert(self, mapper, connection, instance) sqlalchemy.orm.mapper( model, table, extension = ValidationExtension(), **mapper_args ) 

    Вы можете проверить ссылку before_update, потому что не каждый экземпляр здесь фактически обновляется до db.

    «Похоже, что подход Питонов – это делать большинство вещей как свойств»

    Он меняется, но это близко.

    «Если бы я закодировал это на PHP или Java, я бы, вероятно, решил создать методы getter / setter …»

    Хорошо. Это достаточно Pythonic. Ваши функции getter и setter связаны с свойством; это очень хорошо.

    Что за вопрос?

    Вы спрашиваете, как заклинать собственность ?

    Тем не менее, «прозрачная проверка» – если я правильно прочитал ваш пример кода – может быть, не совсем такая хорошая идея.

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

    Вы будете счастливее после шаблона проектирования Django использования формы для проверки, отдельной формы модели.

    Python - лучший язык программирования в мире.