I know there is a way to instrument SQLAlchemy to prepend common prefix
to all columns, is it possible to add a common prefix
to all table names derived from single declarative_base
?
Asked
Active
Viewed 4,623 times
9

canni
- 5,737
- 9
- 46
- 68
1 Answers
9
Use declared_attr
and a customized Base
along the lines of:
from sqlalchemy.ext.declarative import declared_attr
class PrefixerBase(Base):
__abstract__ = True
_the_prefix = 'someprefix_'
@declared_attr
def __tablename__(cls):
return cls._the_prefix + cls.__incomplete_tablename__
class SomeModel(PrefixerBase):
__incomplete_tablename__ = 'sometable'
...
A class marked with __abstract__
will not get a table or mapper created and can act as the extended declarative base.
You could also make it even more implicit using a custom metaclass (originally described here):
from sqlalchemy.ext.declarative.api import DeclarativeMeta
class PrefixerMeta(DeclarativeMeta):
def __init__(cls, name, bases, dict_):
if '__tablename__' in dict_:
cls.__tablename__ = dict_['__tablename__'] = \
'someprefix_' + dict_['__tablename__']
return super().__init__(name, bases, dict_)
Base = declarative_base(metaclass=PrefixerMeta)
class SomeModel(Base):
__tablename__ = 'sometable'
...

Ilja Everilä
- 50,538
- 7
- 126
- 127
-
I've tried the ``@declared_attr`` approach, but it breaks when Single-Table-Inheritance is used, I'll try the metaclass through – canni Jul 07 '16 at 12:51
-
Also, unfortunately as far as I understand this won't work with ``M2M`` join tables, witch if not explicit don't inherit fro declarative base – canni Jul 07 '16 at 12:54
-
No, it would not work for manual `Table`s, as they have nothing to do with declarative. For those consider using a wrapper function or such. – Ilja Everilä Jul 07 '16 at 12:58
-
I'll just make them as a subclass of `declarative`` easy enough, thanks for that – canni Jul 07 '16 at 13:00
-
Btw how does `@declared_attr` break with single table inheritance? Asking out of sheer interest. – Ilja Everilä Jul 07 '16 at 13:01
-
1It converts it to Joined Table Inheritance, by declaring ``__tablename__`` attribute on a subclass (You can use ``@declared_attr.cascading`` and somehow detect that STI, but I don't know how :) ) – canni Jul 07 '16 at 13:07