有没有办法透明地对 SQLAlchemy 对象执行验证? [英] Is there a way to transparently perform validation on SQLAlchemy objects?
问题描述
有没有办法在设置属性之后(或设置时)但在提交会话之前对对象执行验证?
例如,我有一个具有 mac
属性的域模型 Device
.我想确保 mac
属性在添加到数据库或在数据库中更新之前包含有效且经过清理的 mac 值.
看起来 Pythonic 的方法是将大多数事情作为属性来做(包括 SQLAlchemy).如果我用 PHP 或 Java 对此进行编码,我可能会选择创建 getter/setter 方法来保护数据,并让我可以灵活地在域模型本身中处理此问题.
public function mac() { return $this->mac;}公共函数 setMac($mac) {return $this->mac = $this->sanitizeAndValidateMac($mac);}公共函数 sanitizeAndValidateMac($mac) {如果(!preg_match(self::$VALID_MAC_REGEX)){抛出新的 InvalidMacException($mac);}返回 strtolower($mac);}
使用 SQLAlchemy 处理此类情况的 Pythonic 方法是什么?
(虽然我知道验证应该在其他地方处理(即 Web 框架),但我想弄清楚如何处理这些特定于域的验证规则,因为它们肯定会经常出现.)>
更新
我知道在正常情况下我可以使用 property 来做到这一点.关键部分是我将 SQLAlchemy 与这些类一起使用.我不完全理解 SQLAlchemy 是如何发挥其魔力的,但我怀疑自己创建和覆盖这些属性可能会导致不稳定和/或不可预测的结果.
您可以使用 @validates()
装饰器在 SQLAlchemy 类中添加数据验证.
来自文档 - 简单验证器:
<块引用>属性验证器可以引发异常,停止改变属性值的过程,或者可以将给定的值更改为不同的值.
from sqlalchemy.orm import 验证类电子邮件地址(基础):__表名__ = '地址'id = 列(整数,primary_key=True)电子邮件 = 列(字符串)@validates('email')def validate_email(self, key, address):# 你可以使用断言,比如# 在地址中声明'@'# 或引发异常:如果@"不在地址中:raise ValueError('电子邮件地址必须包含@符号.')退货地址
Is there a way to perform validation on an object after (or as) the properties are set but before the session is committed?
For instance, I have a domain model Device
that has a mac
property. I would like to ensure that the mac
property contains a valid and sanitized mac value before it is added to or updated in the database.
It looks like the Pythonic approach is to do most things as properties (including SQLAlchemy). If I had coded this in PHP or Java, I would probably have opted to create getter/setter methods to protect the data and give me the flexibility to handle this in the domain model itself.
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);
}
What is a Pythonic way to handle this type of situation using SQLAlchemy?
(While I'm aware that validation and should be handled elsewhere (i.e., web framework) I would like to figure out how to handle some of these domain specific validation rules as they are bound to come up frequently.)
UPDATE
I know that I could use property to do this under normal circumstances. The key part is that I am using SQLAlchemy with these classes. I do not understand exactly how SQLAlchemy is performing its magic but I suspect that creating and overriding these properties on my own could lead to unstable and/or unpredictable results.
You can add data validation inside your SQLAlchemy classes using the @validates()
decorator.
From the docs - Simple Validators:
An attribute validator can raise an exception, halting the process of mutating the attribute’s value, or can change the given value into something different.
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
这篇关于有没有办法透明地对 SQLAlchemy 对象执行验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!