Nils
Nils

Reputation: 285

How to avoid globals with sqlalchemy

In the general explanation of sqlalchemy there is some basic setup where some globals are used. But how to avoid these globals?

This is the basic setup:

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

databaseName = 'fixedDBName.db'
engine = create_engine('sqlite:///' + databaseName, echo=True)
Base = declarative_base()
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)

from sqlalchemy import Column, Integer, String
class User(declarative_base()):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    nickname = Column(String)

    def __repr__(self):
        return "<User(name='%s', fullname='%s', nickname='%s')>" % (
            self.name, self.fullname, self.nickname)

#Now you can create a session
Session = sessionmaker(bind=engine)
session = Session()

Now this rises some questions for me:
Can i just start a database connection when i need it, close it afterwards and start a new one when i need it again?
How do you use it in your projects?

Do you pack everything that has something to do with the database in a class. So that you can create an instance of that function? Like this:

class sqlcon():
    def __init__(self, databaseName):
        self.engine = create_engine('sqlite:///' + databaseName, echo=True)
        self.Session = sessionmaker(bind=self.engine)
        
    Base = declarative_base()
        
    class User(Base):
        __tablename__ = 'users'

        id = Column(Integer, primary_key=True)
        name = Column(String)
        fullname = Column(String)
        nickname = Column(String)

        def __repr__(self):
            return "<User(name='%s', fullname='%s', nickname='%s')>" % (
                self.name, self.fullname, self.nickname)

    def createTables(self):
        Base.metadata.create_all(self.engine) #doesn´t work - Base is not Defined
        
    Base.metadata.create_all(self.engine) #doesn´t work - self is not Defined

Or Do you pack this inside a function:

def sqlcon(databaseName):
    
   engine = create_engine('sqlite:///' + databaseName, echo=True)
       
   Base = declarative_base()
       
   class User(Base):
       __tablename__ = 'users'

       id = Column(Integer, primary_key=True)
       name = Column(String)
       fullname = Column(String)
       nickname = Column(String)

       def __repr__(self):
           return "<User(name='%s', fullname='%s', nickname='%s')>" % (
               self.name, self.fullname, self.nickname)

   Base.metadata.create_all(engine) 

databaseName = "test_3.db"
alchemy = sqlcon(databaseName)

But then how to create a session and how to access the class User?

Here I need a push in the right direction :/

Upvotes: 1

Views: 685

Answers (1)

Nils
Nils

Reputation: 285

The answer is pretty simple: Base just stays a global!

In all the examples on github you find it this way.

im my case it would be:

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

Base = declarative_base()

class User(Base):
        __tablename__ = 'users'

        id = Column(Integer, primary_key=True)
        name = Column(String)
        fullname = Column(String)
        nickname = Column(String)

        def __repr__(self):
            return "<User(name='%s', fullname='%s', nickname='%s')>" % (
                self.name, self.fullname, self.nickname)


if __name__ == "__main__":
    engine = create_engine("sqlite://")
    Base.metadata.create_all(engine)

    session = Session(engine)

Upvotes: 1

Related Questions