slayedbylucifer
slayedbylucifer

Reputation: 23522

SQLAlchemy: __tablename__ as a variable

I am working on a prototype to pull stocks ticks and dump them to a DB. I want to pass __tablename__ as a parameter to SQLAchemy so that stock ticks for a given stocks gets written down to its own table. (BTW, I am new to SQLAlchemy)

I referred this thread: Python Sqlalchemy - tablename as a variable

And came up with below code:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy import Column, String, Integer, Date


Base = declarative_base()


def create_models(tablename):

    class Stock(Base):

        __tablename__ = tablename

        timestamp = Column(String, primary_key=True)
        ltp = Column(String)

        def __init__(self, timestamp, ltp):
            self.timestamp = timestamp
            self.ltp = ltp

create_models('ABCD')

engine = create_engine('sqlite:////ticks.db')
Base.metadata.create_all(bind=engine)

session_factory = sessionmaker(bind=engine)
Session = scoped_session(session_factory)()

tick = Stock('2019-02-12 09:15:00', '287')
Session.merge(tick)
Session.commit()

But it fails:

Traceback (most recent call last):
  File "quickies.py", line 32, in <module>
    tick = Stock('2019-02-12 09:15:00', '287')
NameError: name 'Stock' is not defined

The error is quite obvious. But then I am unsure how to proceed with __tablename__ as a variable. Any pointers would be of great help.

Upvotes: 4

Views: 19826

Answers (1)

Chetan Ameta
Chetan Ameta

Reputation: 7896

The scope of your Stock class limited to create_models function. To create object of this class outside the function you can return the class from the function and then use it.

have a look on below solution:

def create_models(tablename):

    class Stock(Base):

        __tablename__ = tablename

        timestamp = Column(String, primary_key=True)
        ltp = Column(String)

        def __init__(self, timestamp, ltp):
            self.timestamp = timestamp
            self.ltp = ltp
    return Stock #return the class 

Stock = create_models('ABCD')
tick = Stock('2019-02-12 09:15:00', '287')

have a look at Python scope tutorial for more detail related to scope.

Upvotes: 10

Related Questions