Question

I tried to port the SqlAlchemy single table inheritance example to Camelot

class Person(Entity):
    __tablename__ = 'people'
    id = Column(sqlalchemy.Integer, primary_key=True)
    discriminator = Column('type', sqlalchemy.String(50))
    __mapper_args__ = {'polymorphic_on': discriminator}

    class Admin(EntityAdmin):
        verbose_name = 'Person'
        list_display = ['id','discriminator']

class Engineer(Person):
    __mapper_args__ = {'polymorphic_identity': 'engineer'}
    primary_language = Column(sqlalchemy.String(50))

    class Admin(EntityAdmin):
        verbose_name = 'HR'
        list_display = ['id','discriminator']

But this gives the following error:

  Traceback (most recent call last):
    File "D:/Programming/test/main.py", line 41, in <module>
      start_application()
    File "D:/Programming/test/main.py", line 37, in start_application
      from testing.application_admin import MyApplicationAdmin
    File "D:\Programming\test\testing\application_admin.py", line 6, in <module>
      from testing.model import Engineer, Person
    File "D:\Programming\test\testing\model.py", line 17, in <module>
      class Engineer(Person):
    File "C:\Python27\lib\site-packages\camelot\core\orm.py", line 334, in __init__
      super( EntityMeta, cls ).__init__( classname, bases, dict_ )
    File "C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py", line 1343, in __init__
      _as_declarative(cls, classname, cls.__dict__)
    File "C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py", line 1336, in _as_declarative
      **mapper_args)
    File "C:\Python27\lib\site-packages\sqlalchemy\orm\__init__.py", line 1129, in mapper
      return Mapper(class_, local_table, *args, **params)
    File "C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py", line 197, in __init__
      self._configure_inheritance()
    File "C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py", line 473, in _configure_inheritance
      self.local_table)
    File "C:\Python27\lib\site-packages\sqlalchemy\sql\util.py", line 303, in join_condition
      "between '%s' and '%s'.%s" % (a.description, b.description, hint))
  sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships between 'people' and 'engineer'.

Am I doing something that is not the Camelot way? What's the best way to implement inheritance for the models? I couldn't find anything in the documentation for Camelot.

Edit:

I tried to add the following to the Engineer class

__tablename__ = 'people'
__table_args__ = {'extend_existing': True}

But now after I try to select the Person or Engineer table or if I try to add any of them I get:

C:\Python27\lib\site-packages\sqlalchemy\sql\expression.py:2276: SAWarning: Column u'people_id' on table <sqlalchemy.sql.expression.Select at 0x343fb90; Select object> being replaced by another column with the same key.  Consider use_labels for select() statements.
self[column.key] = column

Any tips?

Was it helpful?

Solution

in your Engineer class, the __tablename__ needs to be set to None, otherwise Camelot will assign a default tablename, and SQLAlchemy will assume multi table inheritance, and thus requires a foreign key relationship.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top