On Wed, Sep 23, 2009 at 10:57 AM, Kevin Horn <kevin.h...@gmail.com> wrote:
> > > On Wed, Sep 23, 2009 at 12:27 AM, Michael Bayer > <mike...@zzzcomputing.com>wrote: > >> >> >> On Sep 22, 2009, at 11:59 AM, Kevin H wrote: >> >> > >> > I'm having some trouble developing my model, and was hoping someone on >> > this list could help... >> > >> > Here's what I want: >> > A BizEntity object >> > A Person and Company object (both descended from BizEntity, using >> > joined table inheritance) >> > A Company.employees attribute, which points to a list of Persons who >> > work for the company >> > A Person.company attribute, which points back to the company that >> > person works for >> > >> > Whenever I try to combine inheritance with this sort of pseudo- >> > adjacency-list, I get really odd things happening when I try to query >> > from the tables...like getting the wrong company back when I query by >> > id. >> > >> > Any ideas out there? Anyone done something like this? >> >> I'm doing this. > > > Howdy, Michael! Knowing that I'm not trying to do something impossible is > definitely a relief. > > >> The first thing to do is to definitely be on 0.5.6 >> at the least. >> > > OK, I'm on 0.5.5, so that's the first thing to fix, I guess. > > >> the next thing is to define the employees/company thing only once, as >> a relation/backref pair on just one of your mapped classes. doing it >> twice will mess things up for sure. >> >> > Good to know, thanks. > > >> your example also mentions a table called "nodes" which from >> everything else mentioned below would be erroneous. you don't need >> remote_side when mapping between Company and Person. >> > > Wow, that's from something _really_ old. Been commented out for a > while...I didn't even notice that. > > >> None of this would cause the wrong "Company" to come back from a >> simple query by id, though. If that is really the effect you're >> seeing then something more fundamental might be amiss. >> > > Looking at it again, it looks like this was caused by a problem in my > tests. I was assuming something I shouldn't have been about the order of > the data I was testing. > > Thanks for the pointers, I'll post back later with results. > > Kevin Horn > > > Still having problems... Here's my new model: # START OF MODEL Base = declarative_base() class BizEntity(Base): __tablename__ = 'biz_entities' id = Column('bizentity_id', Integer, primary_key=True) type = Column('bizentity_type', String(30), nullable=False) __mapper_args__ = {'polymorphic_on': type} class Company(BizEntity): __tablename__ = 'companies' id = Column(Integer, ForeignKey('biz_entities.bizentity_id'), primary_key=True) name = Column('company_name', String(50)) __mapper_args__ = {'polymorphic_identity': 'company'} def __init__(self, company_name): self.name = company_name def __repr__(self): return "<Company('%s')>" % (self.name) class Person(BizEntity): __tablename__ = 'people' id = Column('bizentity_id', Integer, ForeignKey('biz_entities.bizentity_id'), primary_key=True) first_name = Column('first_name', String(50)) middle_init = Column('middle_init', String(1)) last_name = Column('last_name', String(50)) company = relation(Company, backref=backref('employees', order_by=id)) __mapper_args__ = {'polymorphic_identity':'person'} def __init__(self, first_name, middle_init, last_name): self.first_name = first_name self.middle_init = middle_init self.last_name = last_name def __repr__(self): return "<Person('%s %s. %s')>" % (self.first_name, self.middle_init, self.last_name) # END OF MODEL now when I try to use it like this: # START SAMPLE CODE comp1 = Company('Test Company') #~ self.session.add(comp1) #~ self.session.commit() joe = Person('Joe', 'Q', 'Public') joe.company = comp1 self.session.add(joe) self.session.commit() # END SAMPLE CODE I get a traceback like this: Traceback (most recent call last): File "ta_sa_test.py", line 98, in testCreateCompanyWithEmployees self.session.commit() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 673, in commit self.transaction.commit() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 378, in commit self._prepare_impl() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 362, in _prepare_impl self.session.flush() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 1356, in flush self._flush(objects) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 1434, in _flush flush_context.execute() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 261, in execute UOWExecutor().execute(self, tasks) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 753, in execute self.execute_save_steps(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 773, in execute_save_steps self.execute_cyclical_dependencies(trans, task, False) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 789, in execute_cyclical_dependencies self.execute(trans, [t], isdelete) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 753, in execute self.execute_save_steps(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 773, in execute_save_steps self.execute_cyclical_dependencies(trans, task, False) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 789, in execute_cyclical_dependencies self.execute(trans, [t], isdelete) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 753, in execute self.execute_save_steps(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 768, in execute_save_steps self.save_objects(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 759, in save_objects task.mapper._save_obj(task.polymorphic_tosave_objects, trans) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\mapper.py", line 1406, in _save_obj c = connection.execute(statement.values(value_params), params) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\engine\base.py", line 824, in execute return Connection.executors[c](self, object, multiparams, params) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\engine\base.py", line 874, in _execute_clauseelement return self.__execute_context(context) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\engine\base.py", line 896, in __execute_context self._cursor_execute(context.cursor, context.statement, context.parameters[0], context=context) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\engine\base.py", line 950, in _cursor_execute self._handle_dbapi_exception(e, statement, parameters, cursor, context) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\engine\base.py", line 931, in _handle_dbapi_exception raise exc.DBAPIError.instance(statement, parameters, e, connection_invalidated=is_disconnect) IntegrityError: (IntegrityError) PRIMARY KEY must be unique u'INSERT INTO biz_entities (bizentity_id, bizentity_type) VALUES (?, ?)' [1, 'person'] and if I enable the commented-out lines in my sample code, I get a traceback like this: Traceback (most recent call last): File "ta_sa_test.py", line 98, in testCreateCompanyWithEmployees self.session.commit() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 673, in commit self.transaction.commit() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 378, in commit self._prepare_impl() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 362, in _prepare_impl self.session.flush() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 1356, in flush self._flush(objects) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\session.py", line 1434, in _flush flush_context.execute() File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 261, in execute UOWExecutor().execute(self, tasks) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 753, in execute self.execute_save_steps(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 773, in execute_save_steps self.execute_cyclical_dependencies(trans, task, False) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 789, in execute_cyclical_dependencies self.execute(trans, [t], isdelete) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 753, in execute self.execute_save_steps(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 773, in execute_save_steps self.execute_cyclical_dependencies(trans, task, False) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 789, in execute_cyclical_dependencies self.execute(trans, [t], isdelete) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 753, in execute self.execute_save_steps(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 768, in execute_save_steps self.save_objects(trans, task) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\unitofwork.py", line 759, in save_objects task.mapper._save_obj(task.polymorphic_tosave_objects, trans) File "C:\Python26\lib\site-packages\sqlalchemy-0.5.6-py2.6.egg\sqlalchemy\orm\mapper.py", line 1281, in _save_obj (state_str(state), instance_key, state_str(existing))) FlushError: New instance <Person at 0x10dea30> with identity key (<class 'ta_sa_model_declarative.BizEntity'>, (1,)) conflicts with persistent instance <Company at 0x10def50> I've also attempted to define the relation from the Company side, with basically the same results. I'm obviously doing something wrong here, but I just don't know what. This is the first time I've really used SA 0.5, and I haven't used 0.4 in a long while...so I may be trying to do something the "0.4 way" without realizing it. Is there a problem with my model? Am I using the model incorrectly? Where am I going wrong? NOTE: I did upgrade to 0.5.6 from 0.5.5 Kevin Horn --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---