Hello,

I tried to add alias to column in polymorph2.py in examples/polymorph
and it doesn't work.

Here is what I changed in an example (full example is attached):

25c25
<    Column('primary_language', String(50)),
---
>    Column('primary_language', String(50), key='primaryLanguage'),
72c72
<                     engineers.c.primary_language, 
---
>                     engineers.c.primaryLanguage,

When run modified example produses following traceback:
Traceback (most recent call last):
  File "C:\home\Vasily\sqlalchemy\sqlalchemy\examples\polymorph\polymorph3.py", 
line 114, in ?
    c = Company.get(1)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\mapper.py", line 245, 
in get
    return self.query.get(*ident, **kwargs)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\query.py", line 42, in 
get
    return self._get(key, ident, **kwargs)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\query.py", line 204, 
in _get
    return self._select_statement(statement, params=params, 
populate_existing=reload)[0]
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\query.py", line 212, 
in _select_statement
    return self.instances(statement.execute(**params), **kwargs)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\query.py", line 167, 
in instances
    return self.mapper.instances(session=self.session, *args, **kwargs)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\mapper.py", line 388, 
in instances
    self._instance(session, row, imap, result, 
populate_existing=populate_existing)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\mapper.py", line 737, 
in _instance
    self.populate_instance(session, instance, row, identitykey, imap, isnew)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\mapper.py", line 760, 
in populate_instance
    prop.execute(session, instance, row, identitykey, imap, isnew)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\properties.py", line 
807, in execute
    self._instance(session, row, imap, result_list)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\properties.py", line 
837, in _instance
    return self.mapper._instance(session, row, imap, result_list)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\mapper.py", line 736, 
in _instance
    if self.extension.populate_instance(self, session, instance, row, 
identitykey, imap, isnew) is EXT_PASS:
  File "C:\home\Vasily\sqlalchemy\sqlalchemy\examples\polymorph\polymorph3.py", 
line 91, in populate_instance
    Engineer.mapper.populate_instance(session, instance, row, identitykey, 
imap, isnew, frommapper=mapper)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\mapper.py", line 757, 
in populate_instance
    row = frommapper.translate_row(self, row)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\mapper.py", line 752, 
in translate_row
    newrow[c] = newrow[c.key]
  File "C:\Python24\Lib\site-packages\sqlalchemy\util.py", line 189, in 
__getitem__
    return self.decorate[key]
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\properties.py", line 
816, in __getitem__
    return self.row[key]
  File "C:\Python24\Lib\site-packages\sqlalchemy\engine.py", line 867, in 
__getitem__
    return self.__parent._get_col(self.__row, key)
  File "C:\Python24\Lib\site-packages\sqlalchemy\engine.py", line 811, in 
_get_col
    rec = self.props[key.lower()]
KeyError: 'primarylanguage'

Can anyone explain, am I doing something wrong? Or is it a bug in
sqlalchemy?


-- 
Best regards,
 Vasily                          mailto:[EMAIL PROTECTED]
from sqlalchemy import *
import sys

# this example illustrates a polymorphic load of two classes, where each class 
has a very 
# different set of properties

db = create_engine('sqlite://', echo=True, echo_uow=False)

# a table to store companies
companies = Table('companies', db, 
   Column('company_id', Integer, primary_key=True),
   Column('name', String(50))).create()

# we will define an inheritance relationship between the table "people" and 
"engineers",
# and a second inheritance relationship between the table "people" and 
"managers"
people = Table('people', db, 
   Column('person_id', Integer, primary_key=True),
   Column('company_id', Integer, ForeignKey('companies.company_id')),
   Column('name', String(50))).create()
   
engineers = Table('engineers', db, 
   Column('person_id', Integer, ForeignKey('people.person_id'), 
primary_key=True),
   Column('status', String(30)),
   Column('engineer_name', String(50)),
   Column('primary_language', String(50), key='primaryLanguage'),
  ).create()
   
managers = Table('managers', db, 
   Column('person_id', Integer, ForeignKey('people.person_id'), 
primary_key=True),
   Column('status', String(30)),
   Column('manager_name', String(50))
   ).create()

  
# create our classes.  The Engineer and Manager classes extend from Person.
class Person(object):
    def __repr__(self):
        return "Ordinary person %s" % self.name
class Engineer(Person):
    def __repr__(self):
        return "Engineer %s, status %s, engineer_name %s, primary_language %s" 
% (self.name, self.status, self.engineer_name, self.primary_language)
class Manager(Person):
    def __repr__(self):
        return "Manager %s, status %s, manager_name %s" % (self.name, 
self.status, self.manager_name)
class Company(object):
    def __repr__(self):
        return "Company %s" % self.name

# assign plain vanilla mappers
assign_mapper(Person, people)
assign_mapper(Engineer, engineers, inherits=Person.mapper)
assign_mapper(Manager, managers, inherits=Person.mapper)

# create a union that represents both types of joins.  we have to use
# nulls to pad out the disparate columns.
person_join = select(
                [
                    people, 
                    managers.c.status, 
                    managers.c.manager_name,
                    null().label('engineer_name'),
                    null().label('primary_language'),
                    column("'manager'").label('type')
                ], 
                people.c.person_id==managers.c.person_id).union_all(
            select(
                [
                    people, 
                    engineers.c.status, 
                    null().label('').label('manager_name'),
                    engineers.c.engineer_name,
                    engineers.c.primaryLanguage, 
                    column("'engineer'").label('type')
                ],
            people.c.person_id==engineers.c.person_id)).alias('pjoin')

print [c for c in person_join.c]            
    
# MapperExtension object.
class PersonLoader(MapperExtension):
    def create_instance(self, mapper, row, imap, class_):
        if row[person_join.c.type] =='engineer':
            return Engineer()
        elif row[person_join.c.type] =='manager':
            return Manager()
        else:
            return Person()
            
    def populate_instance(self, mapper, session, instance, row, identitykey, 
imap, isnew):
        if row[person_join.c.type] =='engineer':
            Engineer.mapper.populate_instance(session, instance, row, 
identitykey, imap, isnew, frommapper=mapper)
            return False
        elif row[person_join.c.type] =='manager':
            Manager.mapper.populate_instance(session, instance, row, 
identitykey, imap, isnew, frommapper=mapper)
            return False
        else:
            return sqlalchemy.mapping.EXT_PASS

people_mapper = mapper(Person, person_join, extension=PersonLoader())

assign_mapper(Company, companies, properties={
    'employees': relation(people_mapper, lazy=False, private=True)
})

c = Company(name='company1')
c.employees.append(Manager(name='pointy haired boss', status='AAB', 
manager_name='manager1'))
c.employees.append(Engineer(name='dilbert', status='BBA', 
engineer_name='engineer1', primary_language='java'))
c.employees.append(Engineer(name='wally', status='CGG', 
engineer_name='engineer2', primary_language='python'))
c.employees.append(Manager(name='jsmith', status='ABA', 
manager_name='manager2'))
objectstore.commit()

objectstore.clear()

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

print "\n"

dilbert = Engineer.mapper.get_by(name='dilbert')
dilbert.engineer_name = 'hes dibert!'
objectstore.commit()

objectstore.clear()
c = Company.get(1)
for e in c.employees:
    print e, e._instance_key

objectstore.delete(c)
objectstore.commit()


managers.drop()
engineers.drop()
people.drop()
companies.drop()

Reply via email to