Nested composite column types
According to the document
I have a Point
class:
class Point(object): def __init__(self, x, y): self.x = x self.y = y def __composite_values__(self): return self.x, self.y
I could create a mapping to a table vertices
, which represents two points as x1/y1 and x2/y2.
class Vertex(Base): __tablename__ = 'vertices' id = Column(Integer, primary_key=True) x1 = Column(Integer) y1 = Column(Integer) x2 = Column(Integer) y2 = Column(Integer) start = composite(Point, x1, y1) end = composite(Point, x2, y2)
But the problem is that I have two classes Point
and Line
:
class Point(object): def __init__(self, x, y): self.x = x self.y = y class Line(object): def __init__(self, start: Point, end: Point): self.start = start self.end = end
I could not create a mapping to a table Shape
like this:
class Shape(Base): __tablename__ = 'shapes' id = Column(Integer, primary_key=True) a1 = Column(Integer) a2 = Column(Integer) b1 = Column(Integer) b2 = Column(Integer) c1 = Column(Integer) c2 = Column(Integer) d1 = Column(Integer) d2 = Column(Integer) ... line1 = composite(Line, composite(Point, a1, a2), composite(Point, b1, b2)) line2 = composite(Line, composite(Point, c1, c2), composite(Point, d1, d2)) ...
Maybe the example above is not good enough. But the point is that could composite be nested?
Comments (4)


Thanks for your reply ^^ Finally I found a solution for this feature.
In
descriptor_props.py
# line 293 # assert self.key not in dict_ dict_[self.key] = self.composite_class( *[state.dict[key] for key in self._attribute_keys] )
self.composite_class
is the class type predefined incomposite
function. So I created aclassmethod
inLine
, and pass it tocomposite
like this:class Line(object): def __init__(self, start: Point, end: Point): self.start = start self.end = end @classmethod def create(cls, a1, a2, b1, b2): return cls(Point(a1, a2), Point(b1, b2) class Shape(Base): __tablename__ = 'shapes' id = Column(Integer, primary_key=True) a1 = Column(Integer) a2 = Column(Integer) b1 = Column(Integer) b2 = Column(Integer) ... line1 = composite(Line.create, a1, a2, b1, b2) line2 = composite(Line.create, c1, c2, d1, d2)
This solution worked.

sure, if that gets you what you need, technically Point is no longer a "composite" from an ORM point of view, meaning you cant query from it or anything like that....although, you could put a hybrid onto Line so that you could still do
Shape.line1.start == Point(5, 6)
. 
 changed status to closed
you can get nesting of composites pretty much using classmethods and/or
@hybrid_property
on your top composite, this is much simpler than trying to build nesting all the way into the composite descriptor which is already difficult to extend.  Log in to comment
they don't support nesting and to implement this would be very complicated. you're much better off just using hybrid attributes which can get you 95% of what composites do and can be organized in any way you'd like.