4

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!

2
  • "It is my understanding that f'{environment}_some_table' will be be evaluated before runtime" depends on what you mean by "runtime". In the usual sense of the word it is indeed evaluated at runtime. Commented Dec 11, 2017 at 13:24
  • Okay, I actually checked out what the definition of runtime is and you are right. I will modify the question to reflect this. Thanks! Commented Dec 11, 2017 at 15:43

1 Answer 1

5

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 :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.