Sqlalchemy will build a new declarative class from existing ones
I have a use case where over 190 tables are already mapped using declarative_base.
Sometimes I need to create 'staging' tables for some of these tables. The structure of staging tables differs from the original tables in that they have "stage_" preceding the name of the original table and they do not have specific 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 like
from models import Customer
MutatedCustomer = MutateDeclarative(Customer)
But I really don't know what I was doing there, it just works. Could there be any unintended consequences associated with this use, or is there a standard way to generate a class from another declarative class, with the only change being changing the table name and omitting some columns.
Many thanks to the community for explaining this.
source to share
I don't know exactly what your intentions were, so I can't tell if there are unintended consequences. However, this looks quite normal to me. You just create a new class for each call MutateDeclarative()
.
If you run into any problems ("unintended consequences"), you just need to expand yours MutateDeclarative()
to deal with it.
It's a bit like prototype-based inheritance in python.
source to share