Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>One solution would need two parts of implementation:</p> <ol> <li>Implementing a <a href="http://www.sqlalchemy.org/docs/orm/extensions/associationproxy.html#composite-association-proxies" rel="nofollow">composite-association-proxies</a> at <code>Addendum</code></li> <li>Make the new property from (1) <code>Addendum.badges</code> accessible from <code>BaseValueObject</code></li> </ol> <p><strong>Part 1: Implementation of <em>composite-association-proxy</em></strong></p> <p>Add the following properties to <code>Addendum</code>:</p> <pre><code>badges = association_proxy ( 'addendum_badge_maps', 'badge_value', creator=lambda bt, bv: AddendumBadgeMap(badge_type=bt, badge_value=bv) ) </code></pre> <p>and the following to <code>AddendumBadgeMap</code>:</p> <pre><code>addendum = orm.relationship(Addendum, backref=orm.backref( 'addendum_badge_maps', collection_class = attribute_mapped_collection("badge_type"), cascade="all, delete-orphan") ) badge = orm.relationship('Badge', single_parent=True, ) badge_value = association_proxy ('badge', 'value') </code></pre> <p>Now, add a <code>__init__</code>-method to <code>Badge</code>:</p> <pre><code>def __init__(self, value): self.value = value </code></pre> <p>and add the following imports on top:</p> <pre><code>from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.orm.collections import attribute_mapped_collection </code></pre> <p><strong>Part 2: Accessing the <code>badge</code>-proxy from <code>BaseValueObjects</code></strong></p> <p>Link <code>Addendum</code>-objects to <code>BaseValueObjects</code> via adding property to <code>Addendum</code>:</p> <pre><code>base_value_object = orm.relationship( "BaseValueObject", backref=orm.backref('addendum', uselist=False) ) </code></pre> <p>In order to access <code>badegs</code> add the following to <code>BaseValueObjects</code>:</p> <pre><code>def add_badge(self, badge_dict={}, **kwargs): if self.addendum is None: self.addendum = Addendum() badge_dict.update(kwargs) self.addendum.badges = badge_dict _name = association_proxy('addendum', 'name', creator=lambda name: Addendum( name=name, description='', flag=False)) _description = association_proxy('addendum', 'description', creator=lambda description: Addendum( name='', description=description, flag=False)) _flag = association_proxy('addendum', 'flag', creator=lambda flag: Addendum( name='', description='', flag=flag)) @property def badges(self): try: return self.addendum.badges except AttributeError: "In case that there is no ``Addendum`` specified, yet." return None @badges.setter def badges(self, value): self.add_badge(value) @property def name(self): try: return self._name except AttributeError: "In case that there is no ``Addendum`` specified, yet." return "" @name.setter def name(self, value): self._name = value @property def description(self): try: return self._description except AttributeError: "In case that there is no ``Addendum`` specified, yet." return "" @description.setter def description(self, value): self._description = value @property def flag(self): try: return self._flag except AttributeError: "In case that there is no ``Addendum`` specified, yet." return "" @flag.setter def flag(self, value): self._flag = value </code></pre> <p><strong>The complete code</strong></p> <pre><code>import sqlalchemy as sa import sqlalchemy.orm as orm from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.orm.collections import attribute_mapped_collection DBSession = scoped_session(sessionmaker()) Base = declarative_base () ###### ValueObjects: ########## class BaseValueObject(Base): __tablename__ = 'value_objects' id = sa.Column(sa.Integer, primary_key=True) vo_type = sa.Column (sa.String, nullable=False) __mapper_args__ = {'polymorphic_on': vo_type} # Define Badge-Access: def add_badge(self, badge_dict={}, **kwargs): if self.addendum is None: self.addendum = Addendum() badge_dict.update(kwargs) self.addendum.badges = badge_dict _name = association_proxy('addendum', 'name', creator=lambda name: Addendum( name=name, description='', flag=False)) _description = association_proxy('addendum', 'description', creator=lambda description: Addendum( name='', description=description, flag=False)) _flag = association_proxy('addendum', 'flag', creator=lambda flag: Addendum( name='', description='', flag=flag)) @property def badges(self): try: return self.addendum.badges except AttributeError: "In case that there is no ``Addendum`` specified, yet." return None @badges.setter def badges(self, value): self.add_badge(value) @property def name(self): try: return self._name except AttributeError: "In case that there is no ``Addendum`` specified, yet." return "" @name.setter def name(self, value): self._name = value @property def description(self): try: return self._description except AttributeError: "In case that there is no ``Addendum`` specified, yet." return "" @description.setter def description(self, value): self._description = value @property def flag(self): try: return self._flag except AttributeError: "In case that there is no ``Addendum`` specified, yet." return "" @flag.setter def flag(self, value): self._flag = value class ObjectOne(BaseValueObject): __tablename__ = 'objects_one' __mapper_args__ = {'polymorphic_identity': 'ObjectOne'} id = sa.Column(sa.ForeignKey('value_objects.id'), primary_key=True) any_attribute = sa.Column(sa.String) class ObjectTwo(BaseValueObject): __tablename__ = 'objects_two' __mapper_args__ = {'polymorphic_identity': 'ObjectTwo'} id = sa.Column(sa.ForeignKey('value_objects.id'), primary_key=True) any_attribute = sa.Column(sa.String) ############################### ##### Addendum and Bagde ########## class Addendum(Base): __tablename__ = 'addenda' __table_args__ = ( sa.UniqueConstraint('name', 'id'), {} ) id = sa.Column (sa.Integer, primary_key=True) name = sa.Column (sa.String, nullable=False, default='') description = sa.Column (sa.String, nullable=False, default='') flag = sa.Column ( sa.Boolean, nullable=False, default=False) value_object_id = sa.Column ( sa.ForeignKey ('value_objects.id'), unique=True) # Properties: base_value_object = orm.relationship( "BaseValueObject", backref=orm.backref('addendum', uselist=False) ) badges = association_proxy ( 'addendum_badge_maps', 'badge_value', creator=lambda bt, bv: AddendumBadgeMap(badge_type=bt, badge_value=bv) ) class Badge(Base): __tablename__ = 'badges' id = sa.Column (sa.Integer, primary_key=True) value = sa.Column (sa.String) def __init__(self, value): self.value = value class AddendumBadgeMap(Base): __tablename__ = 'addendum_badge_maps' __table_args__ = ( sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('badge_id', 'badge_type'), {} ) id = sa.Column('id', sa.Integer) addendum_id = sa.Column(sa.ForeignKey('addenda.id'), nullable=False) badge_id = sa.Column(sa.ForeignKey('badges.id'), nullable=False) badge_type = sa.Column (sa.String) #Properties: addendum = orm.relationship(Addendum, backref=orm.backref( 'addendum_badge_maps', collection_class = attribute_mapped_collection("badge_type"), cascade="all, delete-orphan") ) badge = orm.relationship('Badge', single_parent=True, ) badge_value = association_proxy ('badge', 'value') ################################### if __name__ == '__main__': engine = sa.create_engine('sqlite:///:memory:', echo=True) DBSession.configure(bind=engine) Base.metadata.create_all(engine) session = DBSession() o1 = ObjectOne(any_attribute="test1") o1.name = "First Object" session.add(o1) session.commit() o1.badges = {'first name': 'Max'} o1.badges['last name'] = 'Mueller' session.commit() print o1.name print o1.description print o1.flag print o1.any_attribute print o1.badges </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload