I have a use case where over 190 tables are already mapped using declarative_base.
Occasionally I need to create 'staging' tables for some of these tables. The staging tables' structure differ from the source tables' in that they have 'stage_' prepended to the source table name, and they don't have certain fields.
This is what I came up with after some trial and error.
from sqlalchemy import Table, Column
def MutateDeclarative(source):
columns = []
omit_columns = ['created_at', 'updated_at']
for c in source.__table__.c:
if c.name not in omit_columns:
columns.append(((c.name,
c.type),
{'primary_key': c.primary_key,
'nullable': c.nullable,
'doc': c.doc,
'default': c.default,
'unique': c.unique,
'autoincrement': c.autoincrement}))
class Stage(Base):
__tablename__ = 'stage_' + source.__tablename__
__table__ = Table('stage_' + source.__tablename__,
Base.metadata, *[Column(*c[0], **c[1]) for c in columns])
return Stage
And this code works. I can call it as such
from models import Customer
MutatedCustomer = MutateDeclarative(Customer)
But I don't really know what I did there, just that it works. Could there be any unintended consequence arising from this usage, or is there a standard way to generate a class from another declarative class with the only change being a change in the table name and the omission of some columns.
Many Thanks to the community for explaining this.