Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Sqlalchemy - tablename as a variable

I am using SQLAlchemy in Python and am declaring my classes inheriting from a declarative base as follows:

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class SomeClass(Base):
    __tablename__ = 'some_table'
    id = Column(Integer, primary_key=True)
    name =  Column(String(50))

As a user I would like to define the __tablename__ as a parameter, and not a hard-coded value , something like this:

class SomeClass(Base):
    __tablename__ = f'{environment}_some_table'
    id = Column(Integer, primary_key=True)
    name =  Column(String(50))

It is my understanding that f'{environment}_some_table' will be be evaluated when I import this package, and therefore I won't be able to modify it at a later stage (i.e. in an interactive notebook). I have a broken piece of code that tries to solve this through nested classes and encapsulation, but I do not manage to reference the instance variable of an outer class.

class Outer:
    def __init__(self, env):
        self.environment = env

    class SomeClass(Base):
        __tablename__ = f'{self.environment}_some_table'
        id = Column(Integer, primary_key=True)
        name =  Column(String(50))

I have read in a couple of SO questions that it is better not to use nested classes since no special relationship is established between these classes. So what kind of design should I use to solve this problem?

Thanks in advance!

like image 868
Pezze Avatar asked Sep 05 '25 03:09

Pezze


1 Answers

you can make all your model definitions inside a function scope so the will be depended on outer arguments:

def create_models(environment):
    class SomeClass(Base):
        __tablename__ = f'{environment}_some_table'
        id = Column(Integer, primary_key=True)
        name =  Column(String(50))
    ...
    globals().update(locals()) # update outer scope if needed

... # some time later
create_models('cheese')
... # now create the db session/engine/etc ... 

another choice to look at is the builtin reload method. check it out :)

like image 146
Yoav Glazner Avatar answered Sep 07 '25 19:09

Yoav Glazner