[storm] Proxy()ing of Reference()s

Bozo Dragojevic bozo.dragojevic at gmail.com
Fri Sep 21 01:48:16 BST 2007


Hello list!

First a great thanks for such a nice gadget!

I'm playing with mapping a database schema which is geared very much
towards Hibernate "one table per subclass" inheritance pattern.

below is a tiny patch that makes my problems go away and I'd like the
feedback if the patch makes sense in the grand scheme of things and/or
how to approach it properly...

The problem goes like this:


from storm.locals import *

class Base(Storm):
  __storm_table__ = "Base"
  id = Int(primary=True)
  itemType = Unicode()

  ownerId = Int()
  owner = Reference(ownerId, "Owner.id") # batteries not included


class BaseInherit(Storm):
  id = Int(primary=True)
  base = Reference(id, Base.id)

  def __init__(self):
    self.base = Base()
    self.base.itemType = unicode(self.__storm_table__)

  ownerId = Proxy(base, Base.ownerId)

  # walking over this one explodes, without the patch
  owner = Proxy(base, Base.owner)

class Derived(BaseInherit):
  __storm_table__ = "Derived"

  specificProp = Unicode()


class Derived2(BaseInherit):
  __storm_table__ = "Derived2"

  specific2Prop = Unicode()




I can then [almost] say:

>>> d = Derived()
>>> d.ownerId = 3
>>> d.owner
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/Users/bozzo/projects/storm-trunk/storm/references.py", line
305, in __get__
    return self._remote_prop.__get__(self._reference.__get__(obj))
  File "/Users/bozzo/projects/storm-trunk/storm/references.py", line
289, in __get__
    obj._remote_prop = resolver.resolve_one(obj._unresolved_prop)
  File "/Users/bozzo/projects/storm-trunk/storm/references.py", line
719, in resolve_one
    return _find_descriptor_obj(self._used_cls, property)
  File "/Users/bozzo/projects/storm-trunk/storm/references.py", line
748, in _find_descriptor_obj
    raise RuntimeError("Reference used in an unknown class")
RuntimeError: Reference used in an unknown class


a "trivial" patch:

=== modified file 'storm/references.py'
--- storm/references.py 2007-08-08 15:02:34 +0000
+++ storm/references.py 2007-09-20 20:58:21 +0000
@@ -715,7 +715,7 @@
             return self.resolve(property)
         elif isinstance(property, basestring):
             return self._resolve_string(property)
-        elif not isinstance(property, Column):
+        elif not isinstance(property, Column) and not
isinstance(property, Reference):
             return _find_descriptor_obj(self._used_cls, property)
         return property



changes the result to a more favorable direction:

>>> d = Derived()
>>> d.ownerId = 3
>>> d.owner
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/Users/bozzo/projects/storm-hack/storm/references.py", line 305,
in __get__
    return self._remote_prop.__get__(self._reference.__get__(obj))
  File "/Users/bozzo/projects/storm-hack/storm/references.py", line 54,
in __get__
    self._build_relation(get_obj_info(local).cls_info.cls)
  File "/Users/bozzo/projects/storm-hack/storm/references.py", line 97,
in _build_relation
    self._remote_key = resolver.resolve(self._remote_key)
  File "/Users/bozzo/projects/storm-hack/storm/references.py", line 710,
in resolve
    return (self.resolve_one(properties),)
  File "/Users/bozzo/projects/storm-hack/storm/references.py", line 717,
in resolve_one
    return self._resolve_string(property)
  File "/Users/bozzo/projects/storm-hack/storm/references.py", line 733,
in _resolve_string
    return registry.get(property_path, self._namespace)
  File "/Users/bozzo/projects/storm-hack/storm/properties.py", line 277,
in get
    raise PropertyPathError("Path '%s' matches no known property."
storm.exceptions.PropertyPathError: Path 'Owner.id' matches no known
property.


Which translates to "It seems to work!" if the example were complete :-)


Thanks for your patience,
Bozzo


p.s.
The other part of "almost works" is that Base is not a real base class
of Derived
so the client code has to be aware of that but this is due to the clumsy
way of
faking inheritance by containment.
What is important to me is that regular users of the API are spared of
all the dirty details...




More information about the storm mailing list