2 messages in com.googlegroups.sqlalchemy[sqlalchemy] backref not working for ...
FromSent OnAttachments
Hong Yuan28 Apr 2007 00:43 
Michael Bayer28 Apr 2007 20:18 
Subject:[sqlalchemy] backref not working for concrete table inheritance?
From:Hong Yuan (hong@gmail.com)
Date:04/28/2007 12:43:26 AM
List:com.googlegroups.sqlalchemy

Hi,

Below is a modified version of the concrete.py example in the example/ polymorph folder.

What I attempted is to add the employees to company, and then find the employees of a particular company.

The employee instances are correctly returned, but the backref 'company' can not be accessed for them:

... 2007-04-28 15:28:09,227 INFO sqlalchemy.engine.base.Engine.0x..10 [1] Manager pointy haired boss manager1 (<class '__main__.Manager'>, (1,), None) Traceback (most recent call last): File "concrete.py", line 84, in <module> print e, e._instance_key, e.company File "c:\python25\lib\site-packages\sqlalchemy-0.3.6-py2.5.egg \sqlalchemy\orm\attributes.py", line 53, in __get__ return self.get(obj) File "c:\python25\lib\site-packages\sqlalchemy-0.3.6-py2.5.egg \sqlalchemy\orm\attributes.py", line 234, in get callable_ = self._get_callable(obj) File "c:\python25\lib\site-packages\sqlalchemy-0.3.6-py2.5.egg \sqlalchemy\orm\attributes.py", line 155, in _get_callable return self.callable_(obj) File "c:\python25\lib\site-packages\sqlalchemy-0.3.6-py2.5.egg \sqlalchemy\orm\strategies.py", line 171, in <lambda> self._register_attribute(self.parent.class_, callable_=lambda i: self.setup_loader(i)) File "c:\python25\lib\site-packages\sqlalchemy-0.3.6-py2.5.egg \sqlalchemy\orm\strategies.py", line 177, in setup_loader prop = mapper.object_mapper(instance).props[self.key] KeyError: 'company'

How can I make backref work with concrete table inheritance? It works in the simple.py.

Best Regards, Hong Yuan

============== The example code below ========================

from sqlalchemy import *

metadata = MetaData()

managers_table = Table('managers', metadata, Column('employee_id', Integer, primary_key=True), Column('name', String(50)), Column('company_id', Integer, ForeignKey('companies.company_id')), Column('manager_data', String(40)) )

engineers_table = Table('engineers', metadata, Column('employee_id', Integer, primary_key=True), Column('company_id', Integer, ForeignKey('companies.company_id')), Column('name', String(50)), Column('engineer_info', String(40)) )

companies = Table('companies', metadata, Column('company_id', Integer, primary_key=True), Column('name', String(50)))

engine = create_engine('sqlite:///', echo=True) metadata.create_all(engine)

class Employee(object): def __init__(self, name): self.name = name def __repr__(self): return self.__class__.__name__ + " " + self.name

class Manager(Employee): def __init__(self, name, manager_data): self.name = name self.manager_data = manager_data def __repr__(self): return self.__class__.__name__ + " " + self.name + " " + self.manager_data

class Engineer(Employee): def __init__(self, name, engineer_info): self.name = name self.engineer_info = engineer_info def __repr__(self): return self.__class__.__name__ + " " + self.name + " " + self.engineer_info

class Company(object): def __init__(self, **kwargs): for key, value in kwargs.iteritems(): setattr(self, key, value) def __repr__(self): return "Company %s" % self.name

pjoin = polymorphic_union({ 'manager':managers_table, 'engineer':engineers_table }, 'type', 'pjoin')

employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type) manager_mapper = mapper(Manager, managers_table, inherits=employee_mapper, concrete=True, polymorphic_identity='manager') engineer_mapper = mapper(Engineer, engineers_table, inherits=employee_mapper, concrete=True, polymorphic_identity='engineer')

mapper(Company, companies, properties={ 'employees': relation(Employee, lazy=True, private=True, backref='company') })

session = create_session(bind_to=engine)

m1 = Manager("pointy haired boss", "manager1") e1 = Engineer("wally", "engineer1") e2 = Engineer("dilbert", "engineer2") c = Company(name='company1') c.employees.append(m1) c.employees.append(e1) c.employees.append(e2)

session.save(c) session.flush() session.clear()

c = session.query(Company).get(1) for e in c.employees: print e, e._instance_key, e.company