On Aug 26, 2011, at 9:36 PM, Michael Bayer wrote:

> the error message here isn't fantastic but I think you mean to say:
> 
> oa = ObjectAssociation()
> o2.relate_down.append(oa)
> o.relate_up.append(oa)
> 
> as relate_up/relate_down accept ObjectAssociation objects, not Object
> objects, as members.

Oops, that sounds plausible. I guess I was tacitly assuming that
SQLalchemy would somehow abstract away from the association
object and let me create relations between the Objects directly (but then how 
would I define
the extra attributes of the association?).

    Thanks!
 
> 
> 
> 
> On Aug 26, 2:53 pm, Thomas Jacob <ja...@internet24.de> wrote:
>> Hello List
>> 
>> I'd like to define a many-to-many relationship using the declarative
>> syntax between a table to itself, but employing an association
>> object (since I require the association to have attributes
>> also).
>> 
>> Here's what I tried:
>> 
>> #=================================================================
>> 
>> from sqlalchemy import *
>> from sqlalchemy.ext.declarative import declarative_base
>> from sqlalchemy.orm import sessionmaker, relation, backref
>> 
>> DB_engine = create_engine('sqlite:///:memory:', echo=True)
>> DB_Base = declarative_base(bind=DB_engine)
>> DB_Session = sessionmaker()
>> DB_Session.configure(bind=DB_engine)
>> DB_session =  DB_Session()
>> 
>> class Object(DB_Base):
>>     __tablename__ = 'object'
>> 
>>     object_id = Column(Integer, primary_key=True)
>>     label = Column(Text)
>> 
>> class ObjectAssociation(DB_Base):
>>     __tablename__ = 'object_association'
>>     __table_args__ = (
>>         PrimaryKeyConstraint('left_object_id', 'right_object_id'),
>>         {}
>>     )
>> 
>>     left_object_id = Column(Integer, ForeignKey('object.object_id'))
>>     right_object_id = Column(Integer, ForeignKey('object.object_id'))
>>     label = Column(Text)
>> 
>>     left_object = relation(Object,
>>         primaryjoin=(left_object_id==Object.object_id),
>>         backref=backref("relate_down")
>>         )
>>     right_object = relation(Object,
>>         primaryjoin=(right_object_id==Object.object_id),
>>         backref=backref("relate_up")
>>         )
>> 
>> DB_Base.metadata.create_all()
>> 
>> o = Object()
>> o.label = 'Object1'
>> 
>> o2 = Object()
>> o2.label = 'Object2'
>> 
>> o2.relate_down.append(o)
>> 
>> DB_session.commit()
>> 
>> #=================================================================
>> 
>> But this raises an exception:
>> 
>> #=================================================================
>> 
>> 2011-08-26 20:48:28,422 INFO sqlalchemy.engine.base.Engine PRAGMA
>> table_info("object")
>> 2011-08-26 20:48:28,422 INFO sqlalchemy.engine.base.Engine ()
>> 2011-08-26 20:48:28,422 INFO sqlalchemy.engine.base.Engine PRAGMA
>> table_info("object_association")
>> 2011-08-26 20:48:28,422 INFO sqlalchemy.engine.base.Engine ()
>> 2011-08-26 20:48:28,423 INFO sqlalchemy.engine.base.Engine
>> CREATE TABLE object (
>>         object_id INTEGER NOT NULL,
>>         label TEXT,
>>         PRIMARY KEY (object_id)
>> )
>> 
>> 2011-08-26 20:48:28,423 INFO sqlalchemy.engine.base.Engine ()
>> 2011-08-26 20:48:28,423 INFO sqlalchemy.engine.base.Engine COMMIT
>> 2011-08-26 20:48:28,423 INFO sqlalchemy.engine.base.Engine
>> CREATE TABLE object_association (
>>         left_object_id INTEGER,
>>         right_object_id INTEGER,
>>         label TEXT,
>>         PRIMARY KEY (left_object_id, right_object_id),
>>         FOREIGN KEY(left_object_id) REFERENCES object (object_id),
>>         FOREIGN KEY(right_object_id) REFERENCES object (object_id)
>> )
>> 
>> 2011-08-26 20:48:28,423 INFO sqlalchemy.engine.base.Engine ()
>> 2011-08-26 20:48:28,424 INFO sqlalchemy.engine.base.Engine COMMIT
>> Traceback (most recent call last):
>>   File "bug.py", line 53, in <module>
>>     o2.relate_down.append(o)
>>   File
>> "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/collections.py",
>> line 952, in append
>>     item = __set(self, item, _sa_initiator)
>>   File
>> "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/collections.py",
>> line 927, in __set
>>     item = getattr(executor, 'fire_append_event')(item, _sa_initiator)
>>   File
>> "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/collections.py",
>> line 618, in fire_append_event
>>     item, initiator)
>>   File
>> "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/attributes.py",
>> line 745, in fire_append_event
>>     value = fn(state, value, initiator or self)
>>   File
>> "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/attributes.py",
>> line 943, in emit_backref_from_collection_append_event
>>     child_state.manager[key].impl.append(
>> KeyError: 'left_object'
>> 
>> #===================================================================
>> 
>> Is this a bug? Am I doing something wrong?
>> 
>> Any clue as to what is going on here would be greatly appreciated.
>> 
>> The platform I ran this on was  Ubuntu 10.04's Python 2.6.5 + SQLAlchemy
>> 0.7.2.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> 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 sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to