Michael Löffler | 18 Aug 2011 13:25

Validation of referenced objects

Hi list!

I'm looking for an elegant way, to validate referenced objects. Let's 
say, I have a table 'persons' with the attributes 'father', 'mother', 
'age', and I want to validate for example, that the parents are actually 
older then their children. So I have code like

class Person(object):
     __storm_table__ = 'persons'
     id = Int(primary=True)
     father_id = Int()
     father = Reference(id, father_id)
     ...

Adding a validator to the father_id attribute would have to look up the 
object by the id first, and then process the validation, even if the 
reference already knows the referenced object. This extra lookup would 
be inefficient in my eyes. On the other side, a Reference doesn't seem 
to have a validation mechanism. Would it be wise, to somehow subclass 
Reference, or do I better stick with the lookup of the id? Are there any 
side effects I should be aware of?

Regards,

Michael

Jamu Kakar | 18 Aug 2011 14:00
Picon
Gravatar

Re: Validation of referenced objects

Hi Michael,

On Thu, Aug 18, 2011 at 1:25 PM, Michael Löffler <ml <at> mldesign.net> wrote:
> I'm looking for an elegant way, to validate referenced objects. Let's say, I
> have a table 'persons' with the attributes 'father', 'mother', 'age', and I
> want to validate for example, that the parents are actually older then their
> children. So I have code like
>
> class Person(object):
>    __storm_table__ = 'persons'
>    id = Int(primary=True)
>    father_id = Int()
>    father = Reference(id, father_id)
>    ...
>
> Adding a validator to the father_id attribute would have to look up the
> object by the id first, and then process the validation, even if the
> reference already knows the referenced object. This extra lookup would be
> inefficient in my eyes. On the other side, a Reference doesn't seem to have
> a validation mechanism. Would it be wise, to somehow subclass Reference, or
> do I better stick with the lookup of the id? Are there any side effects I
> should be aware of?

There's no great way to do this in Storm, right now.  You could define
a validator for the father_id property, as you suggest, but one
concern is that creating many Person instances will run a lot of
individual queries to fetch the references.  If you only create one at
a time, it's not a big deal, but if you create many instances you
probably want to write a function create_people(...) that can fetch
the related objects using a single query and perform the validation in
(Continue reading)

Michael Löffler | 23 Aug 2011 12:16

Re: Validation of referenced objects

Hi Jamu,

thanks for your fast answer. Unfortunatly, I was not really happy with 
the suggested solutions. So I solved the problem differently now. I 
worked around the problem by subclassing Reference in order to extend it 
with validation features. I tried to be as less intrusive to the 
Reference class as possible and to copy the validation mechanism for the 
Variables as good as possible. It's still not filling the 
validator_attribute field automatically, but nevertheless, it could also 
be useful for others, so I'd like to share it:

class ValidatingReference(storm.references.Reference):
     def __init__(self, *args, **kwargs):
         validator = kwargs.pop('validator', None)
         if validator is not None:
             self._validator = validator
             self._validator_attribute = 
kwargs.pop('validator_attribute', None)
         storm.references.Reference.__init__(self, *args, **kwargs)

     def __set__(self, local, remote, from_db=False):
         local = get_obj_info(local).get_obj()
         remote = get_obj_info(remote).get_obj()

         if self._validator and not from_db:
             remote = self._validator(local,
                         self._validator_attribute, remote)
         storm.references.Reference.__set__(self, local, remote)

Am 18.08.2011 15:00, schrieb Jamu Kakar:
(Continue reading)

James Henstridge | 26 Aug 2011 07:50
Picon
Gravatar

Re: Validation of referenced objects

On Thu, Aug 18, 2011 at 7:25 PM, Michael Löffler <ml@...> wrote:
> Hi list!
>
> I'm looking for an elegant way, to validate referenced objects. Let's say, I
> have a table 'persons' with the attributes 'father', 'mother', 'age', and I
> want to validate for example, that the parents are actually older then their
> children. So I have code like
>
> class Person(object):
>    __storm_table__ = 'persons'
>    id = Int(primary=True)
>    father_id = Int()
>    father = Reference(id, father_id)
>    ...
>
> Adding a validator to the father_id attribute would have to look up the
> object by the id first, and then process the validation, even if the
> reference already knows the referenced object. This extra lookup would be
> inefficient in my eyes. On the other side, a Reference doesn't seem to have
> a validation mechanism. Would it be wise, to somehow subclass Reference, or
> do I better stick with the lookup of the id? Are there any side effects I
> should be aware of?

If you're talking about something like:

    father = store.get(Person, child.father_id)

Then that won't result in a database query if the father has been
loaded recently in the same transaction. It shouldn't be that
inefficient to use in a validator function.
(Continue reading)


Gmane