On Wednesday, March 23, 2011 1:40:30 AM UTC+1, Michael Bayer wrote:
>
>
> On Mar 22, 2011, at 6:03 PM, Debilski wrote:
>
> > Hi,
> > I’m having a problem with the collection append method in a many-to-
> > many relationship with association object. Basically, I’d like to
> > connect classes of type Entity through a Context object (which holds a
> > description of the connection type). Programmatically, it should go
> > like
> >
> > experiment = Entity()
> > observer = Entity()
> > experiment.connect("has Observer", observer)
> > print experiment.connected # prints [observer]
> >
> > However, what happens is that this code results in observer being
> > printed twice unless some other operation occurred before that
> > statement. It is not really clear to me why this happens. The code is
> > as follows:
>
> so when you append to a list, if multiple appends of the same object (same
> identity) occur, you'll see those duplicated elements in the list as it is
> in memory. Once the session is committed, the attribute is expired - on a
> load back, relational rules mean you can only get the element from a
> one-to-many back once, so then you see it once.
>
> The element is duplicated because of this:
>
> context = Context(back_referenced=self,
> connected=connection_object, connection_type=connection_type)
> self.connections.append(context)
>
> Context(back_referenced=self) triggers an event based on the backref in the
> "backreferenced" relationship that also appends the item to the "connected"
> list. The "connected.append" afterwards does the same thing a second time.
> "Context.back_referenced" and "Entity.connections" are two sides of the
> same relational coin, and establishment via relationship/backref establishes
> this behavior in memory pre-flush as well.
>
Thank you! Of course, when I specify the back_referenced manually, there is
no need to use append. Seems pretty clear.
Cheers
/rike
> >
> > from sqlalchemy import Column, ForeignKey, String, Integer,
> > create_engine
> > from sqlalchemy.orm import relationship, backref, scoped_session,
> > sessionmaker
> > from sqlalchemy.ext.declarative import declarative_base
> > Base = declarative_base()
> >
> > class Entity(Base):
> > __tablename__ = "entities"
> > id = Column('id', Integer, primary_key=True)
> >
> > def connect(self, connection_type, connection_object):
> > """Connect this entity with connection_object via the
> > connection_type."""
> > context = Context(back_referenced=self,
> > connected=connection_object, connection_type=connection_type)
> > self.connections.append(context)
> >
> > @property
> > def connected(self):
> > return [c.connected for c in self.connections]
> >
> >
> > class Context(Base):
> > __tablename__ = "contexts"
> > entity_id = Column('entity_id', Integer,
> > ForeignKey(Entity.id), primary_key=True)
> > connected_id = Column('connected_id', Integer,
> > ForeignKey(Entity.id), primary_key=True)
> >
> > connection_type = Column('connection_type', String(500))
> >
> > # Each entity can have a context of related entities
> > back_referenced = relationship(Entity,
> > backref=backref('connections', cascade="all"),
> > primaryjoin=entity_id==Entity.id)
> >
> > connected = relationship(Entity,
> > backref=backref('back_references', cascade="all"),
> > primaryjoin=connected_id==Entity.id)
> >
> > def __repr__(self):
> > return "Context(entity_id={id!s}, connected_id={cid!s},
> > connection_type={type})".format(id=self.entity_id,
> > cid=self.connected_id, type=self.connection_type)
> >
> > def __str__(self):
> > return "Context({e} has {t}
> > {c})".format(e=self.back_referenced, t=self.connection_type,
> > c=self.connected)
> >
> > session = scoped_session(sessionmaker(autocommit=True))
> > engine = create_engine("sqlite://")
> > session(bind=engine)
> > Base.metadata.create_all(engine)
> >
> > e1 = Entity()
> > e2 = Entity()
> >
> > session.add(e1)
> > session.add(e2)
> >
> > e1.connect("C", e2)
> >
> > print e1.connected
> > print "Number of connections to e1", len(e1.connected)
> >
> > # prints:
> > # [<__main__.Entity object at 0x101613dd0>, <__main__.Entity object at
> > 0x101613dd0>]
> > # Number of connections to e1 2
> >
> > Is there anything I can do to get the correct number of entities back?
> >
> > Thanks
> > /rike
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> [email protected].
> > For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
> >
>
>
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.