views:

199

answers:

1

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.

A: 

"It looks like the Pythonic approach is to do most things as properties"

It varies, but that's close.

"If I had coded this in PHP or Java, I would probably have opted to create getter/setter methods..."

Good. That's Pythonic enough. Your getter and setter functions are bound up in a property; that's pretty good.

What's the question?

Are you asking how to spell property?

However, "transparent validation" -- if I read your example code correctly -- may not really be all that good an idea.

Your model and your validation should probably be kept separate. It's common to have multiple validations for a single model. For some users, fields are optional, fixed or not used; this leads to multiple validations.

You'll be happier following the Django design pattern of using a Form for validation, separate form the model.

S.Lott
I am not sure what sort of magic SQLAlchemy uses to bind to the Model class properties. I would not assume it is safe to define my own `mac = property()` on my class. I think my question is is this safe to do? If so, are there any gotchas? If not, what are some other alternatives?
Beau Simensen
There is no magic. That are no gotchas. The alternative is what we generally do: we do validation *outside* the model class, making it even simpler. Define your validation *outside* the model, and then you don't have to worry about any of this.
S.Lott