I have a base "abstract" table and an "entity" table that inherits the abstract columns and adds its own:
class AbstractTable(Base):
__abstract__ = True
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(Unicode)
value = Column(Unicode)
class EntityTable(AbstractTable):
entity_id = Column(Integer)
__table_args__ = ()
I need a unique composite index on entity_id and name. To the __table_args__, I add:
Index('entity_id_name', entity_id, AbstractTable.name, unique=True)
Once this is added, I receive the following stack trace:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "[...]/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 609, in __init__
DeclarativeMeta.__init__(self, name, bases, d)
File "[...]/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 64, in __init__
_as_declarative(cls, classname, cls.__dict__)
File "[...]/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 88, in _as_declarative
_MapperConfig.setup_mapping(cls, classname, dict_)
File "[...]/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 103, in setup_mapping
cfg_cls(cls_, classname, dict_)
File "[...]/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 131, in __init__
self._setup_table()
File "[...]/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 395, in _setup_table
**table_kw)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 439, in __new__
metadata._remove_table(name, schema)
File "[...]/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 434, in __new__
table._init(name, metadata, *args, **kw)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 518, in _init
self._init_items(*args)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 79, in _init_items
item._set_parent_with_dispatch(self)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/base.py", line 431, in _set_parent_with_dispatch
self._set_parent(parent)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 3367, in _set_parent
ColumnCollectionMixin._set_parent(self, table)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 2611, in _set_parent
self.columns.add(col)
File "[...]/lib/python2.7/site-packages/sqlalchemy/sql/base.py", line 503, in add
"Can't add unnamed column to column collection")
ArgumentError: Can't add unnamed column to column collection
Clearly it doesn't like that, although as best I can figure this should work as written.
I can silence the error if I change AbstractTable.name in the index definition to the string 'name', like:
Index('entity_id_name', entity_id, 'name', unique=True)
... but I've never had to use string column names in an index before. Am I incorrect in thinking that I should be able to reference the abstract columns in this way?
Yes to being incorrect. Inheritance in case of abstract declarative base classes works so that it creates copies of found Columns from the parent to child. Add to that that the columns in an abstract base class aren't initialized in the same fashion as in concrete classes. So you're referencing the wrong class' uninitialized column. Either define the column as a string, or define the Index externally after the EntityTable class, as described here.
class EntityTable(AbstractTable):
...
# The class has been constructed and has usable columns.
Index('entity_id_name', EntityTable.entity_id, EntityTable.name, unique=True)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With