support @declared_attr as standalone getter? or just set up __tablename__, others explicitly
Issue #3331
resolved
The following code works without any problems in sqlalchemy 0.9.9 but fails in 1.0.0b1:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr
Base = declarative_base()
class Abstract1(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
class Concrete1(Abstract1, Base):
id = sa.Column(sa.Integer, primary_key=True)
Abstract1.__tablename__
Concrete1.__tablename__
The exception:
#!
<ipython-input-8-1445e04c4c3b> in <module>()
----> 1 Concrete1.__tablename__
/home/pieter/.virtualenvs/proigia_encryption/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyc in __get__(desc, self, cls)
180 except KeyError:
181 raise exc.InvalidRequestError(
--> 182 "@declared_attr called outside of the "
183 "declarative mapping process; is declarative_base() being "
184 "used correctly?")
InvalidRequestError: @declared_attr called outside of the declarative mapping process; is declarative_base() being used correctly?
Comments (4)
-
repo owner -
repo owner - changed title to support @declared_attr as standalone getter? or just set up __tablename__, others explicitly
- changed milestone to 1.0
- marked as proposal
-
repo owner - changed status to resolved
- Loosened some restrictions that were added to
@declared_attr
objects, such that they were prevented from being called outside of the declarative process; this is related to the enhancements of#3150which allow@declared_attr
to return a value that is cached based on the current class as it's being configured. The exception raise has been removed, and the behavior changed so that outside of the declarative process, the function decorated by@declared_attr
is called every time just like a regular@property
, without using any caching, as none is available at this stage. fixes#3331
→ <<cset cd076470baf2>>
-
repo owner ill put out beta2 soon and this will work again.
- Log in to comment
OK,
__tablename__
wasn't intended as a getter, typically you'd use__table__.name
, because__tablename__
is not even guaranteed to be present. will see if there's some way to allow both cases here.