Problem with polymorph mappers

Issue #158 resolved
Former user created an issue

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

Here's a changes I made:

25c25
<    Column('primary_language', String(50)),
---
>    Column('primary_language', String(50), key='primaryLanguage'),
41c41
<         return "Engineer %s, status %s, engineer_name %s, primary_language %s" % (self.name, self.status, self.engineer_name, self.primary_language)
---
>         return "Engineer %s, status %s, engineer_name %s, primaryLanguage %s" % (self.name, self.status, self.engineer_name, self.primaryLanguage)
72c72
<                     engineers.c.primary_language, 
---
>                     engineers.c.primaryLanguage,

Full example is attached.

And it produces following error:

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](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](c) = newrow[c.key](c.key)
  File "C:\Python24\Lib\site-packages\sqlalchemy\util.py", line 189, in __getitem__
    return self.decorate[key](key)
  File "C:\Python24\Lib\site-packages\sqlalchemy\mapping\properties.py", line 816, in __getitem__
    return self.row[key](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()](key.lower())
KeyError: 'primarylanguage'

It seems that problem is in file mapping/mapper.py lines 751-752:

        for c in tomapper.table.c:
            newrow[c](c) = newrow[c.key](c.key)

I changed it to

        for c in tomapper.table.c:
            newrow[c](c) = newrow[c.name](c.name)

And examples work. All other parts of sqlalchemy seem to still work. So that's perhaps a solution to shown problem.

Here's a diff of changes:

Index: lib/sqlalchemy/mapping/mapper.py
===================================================================
--- lib/sqlalchemy/mapping/mapper.py    (revision 1277)
+++ lib/sqlalchemy/mapping/mapper.py    (working copy)
@@ -749,7 +749,7 @@
         for c in self.table.c:
             newrow[c.key](c.key) = row[c](c)
         for c in tomapper.table.c:
-            newrow[c](c) = newrow[c.key](c.key)
+            newrow[c](c) = newrow[c.name](c.name)
         return newrow

     def populate_instance(self, session, instance, row, identitykey, imap, isnew, frommapper=None):

Comments (3)

  1. Mike Bayer repo owner

    OK, committed in changeset:1281 so ill mark as fixed....however the whole "key/name" dichotomy is one Id like to remove totally since its an extra complexity to support...its probably better if you use custom property names (or just keep supporting fixes for "key" as they come up....)

  2. Log in to comment