tutorial soup library find_next_sibling python validation model dns sqlalchemy

python - soup - ¿Hay alguna manera de realizar la validación de forma transparente en objetos SQLAlchemy?



python soup find (3)

"Parece que el enfoque Pythonic es hacer la mayoría de las cosas como propiedades"

Varía, pero eso está cerca.

"Si hubiera codificado esto en PHP o Java, probablemente habría optado por crear métodos getter / setter ..."

Bueno. Eso es lo suficientemente pitónico. Sus funciones get y setter están ligadas a una propiedad; eso es bastante bueno.

¿Cuál es la pregunta?

¿Estás preguntando cómo deletrear propiedad ?

Sin embargo, la "validación transparente", si leo su código de ejemplo correctamente, puede que no sea una buena idea.

Su modelo y su validación probablemente deberían mantenerse separados. Es común tener múltiples validaciones para un solo modelo. Para algunos usuarios, los campos son opcionales, fijos o no utilizados; esto lleva a validaciones múltiples.

Serás más feliz siguiendo el patrón de diseño de Django de usar un Formulario para la validación, separado del modelo.

¿Hay alguna manera de realizar la validación en un objeto después (o como) de que se hayan establecido las propiedades pero antes de que se haya comprometido la sesión?

Por ejemplo, tengo un Device modelo de dominio que tiene una propiedad de mac . Me gustaría asegurarme de que la propiedad mac contenga un valor mac válido y sanitizado antes de que se agregue o actualice en la base de datos.

Parece que el enfoque Pythonic es hacer la mayoría de las cosas como propiedades (incluida SQLAlchemy). Si hubiera codificado esto en PHP o Java, probablemente habría optado por crear métodos getter / setter para proteger los datos y darme la flexibilidad para manejar esto en el propio modelo de dominio.

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); }

¿Cuál es una manera pitonica de manejar este tipo de situaciones usando SQLAlchemy?

(Si bien conozco esa validación y debería tratarse en otro lugar (es decir, el marco web), me gustaría averiguar cómo manejar algunas de estas reglas de validación específicas de dominio, ya que están destinadas a aparecer con frecuencia).

ACTUALIZAR

Sé que podría usar la propiedad para hacer esto en circunstancias normales. La parte clave es que estoy usando SQLAlchemy con estas clases. No entiendo exactamente cómo SQLAlchemy está realizando su magia, pero sospecho que crear y reemplazar estas propiedades por mi cuenta podría generar resultados inestables y / o impredecibles.


Puede agregar validación de datos dentro de sus clases SQLAlchemy usando el decorador @validates() .

De los documentos - Validadores simples :

Un validador de atributo puede generar una excepción, deteniendo el proceso de mutación del valor del atributo, o puede cambiar el valor dado en algo diferente.

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


Sí. Esto se puede hacer muy bien usando 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 )

Es posible que desee comprobar la referencia before_update porque no todas las instancias aquí se actualizan realmente a la base de datos.