有没有办法透明地对 SQLAlchemy 对象执行验证? [英] Is there a way to transparently perform validation on SQLAlchemy objects?

查看:44
本文介绍了有没有办法透明地对 SQLAlchemy 对象执行验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在设置属性之后(或设置时)但在提交会话之前对对象执行验证?

例如,我有一个具有 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆