[Sqlalchemy-tickets] Issue #4090: declared_attr.cascading doesn't work for __tablename__ (zzzeek/sq
Brought to you by:
zzzeek
From: David L. <iss...@bi...> - 2017-09-26 04:09:50
|
New issue 4090: declared_attr.cascading doesn't work for __tablename__ https://bitbucket.org/zzzeek/sqlalchemy/issues/4090/declared_attrcascading-doesnt-work-for David Lord: I noticed this while fixing tablename generation in Flask-SQLAlchemy. The reason I use the metaclass instead of `declared_attr` is because the `cascading` option doesn't work for `__tablename__`. Instead, it's treated like a normal declared attr, where once an intermediate class sets a value, that's used going forward. You also showed `declared_attr.cascading` for `__tablename__` in the docs for `__table_cls__`, which won't work as intended: https://gerrit.sqlalchemy.org/plugins/gitiles/zzzeek/sqlalchemy/+/refs/changes/27/527/2/doc/build/orm/extensions/declarative/api.rst#137 ```python3 import sqlalchemy as sa from sqlalchemy.ext.declarative import declarative_base, declared_attr class Base: @declared_attr.cascading def __tablename__(cls): return cls.__name__.lower() Base = declarative_base(cls=Base) class User(Base): id = sa.Column(sa.Integer, primary_key=True) class User2(User): __tablename__ = 'user2' id = sa.Column(sa.ForeignKey(User.id), primary_key=True) class User3(User2): id = sa.Column(sa.ForeignKey(User2.id), primary_key=True) engine = sa.create_engine('sqlite://', echo=True) Base.metadata.create_all(engine) ``` ```pytb Traceback (most recent call last): File "/home/david/Projects/flask-sqlalchemy/example.py", line 23, in <module> class User3(User2): File "/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.6/site-packages/sqlalchemy/ext/declarative/api.py", line 64, in __init__ _as_declarative(cls, classname, cls.__dict__) File "/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.6/site-packages/sqlalchemy/ext/declarative/base.py", line 88, in _as_declarative _MapperConfig.setup_mapping(cls, classname, dict_) File "/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.6/site-packages/sqlalchemy/ext/declarative/base.py", line 103, in setup_mapping cfg_cls(cls_, classname, dict_) File "/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.6/site-packages/sqlalchemy/ext/declarative/base.py", line 131, in __init__ self._setup_table() File "/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.6/site-packages/sqlalchemy/ext/declarative/base.py", line 395, in _setup_table **table_kw) File "/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 421, in __new__ "existing Table object." % key) sqlalchemy.exc.InvalidRequestError: Table 'user2' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object. ``` |