Reputation: 5029
I am writing Python application to operate on Postgres database with SQLAlchemy. Specified the database information in a settings.py
DATABASE = {
'drivername': 'postgres',
'host': 'xyz.com',
'port': '5432',
'username': 'user',
'password': 'pass',
'database': 'db_dev'
}
Then I created a db_connection.py
with a method to create a connection.
from sqlalchemy import *
from sqlalchemy.engine.url import URL
from . import settings
def get_engine():
return create_engine(URL(**settings.DATABASE))
I want to have another module db_ops.py
that has all the database operation func1
, func2
methods and call them in the main application module
engine = db.connection.get_engine()
db_ops.func1()
db_ops.func2()
And that means I will need to pass engine
as a parameter to these methods.
func1(engine)
func2(engine)
Somehow I don't like the idea of making db connection as method parameter. Is there a better way to do it?
Upvotes: 2
Views: 3790
Reputation: 20548
An Engine
is not a connection. You can think of it as a connection pool. Usually the most natural way to to use an engine is to put it at the global level. In your case, you can put it in db_connection.py
:
from sqlalchemy import *
from sqlalchemy.engine.url import URL
from . import settings
engine = create_engine(URL(**settings.DATABASE))
Then, you can import it in your db_ops
module:
from db_connection import engine
def func1():
engine.execute(...)
However, for a series of related queries you probably want to execute them in a single transaction, which necessitates passing around the actual connection:
with engine.begin() as connection:
func1(connection)
func2(connection)
To solve this problem, we have the concept of a scoped_session
(again, also at the global level):
engine = create_engine(URL(**settings.DATABASE))
Session = scoped_session(sessionmaker(bind=engine))
Each time Session
is called, it checks to see if there's already a session for the current thread, and creates it if it doesn't, obviating the need to pass around the connection:
from db_connection import Session
def func1():
Session.execute(...)
In the caller of db_ops
functions:
try:
func1()
func2()
Session.commit()
finally:
Session.remove()
Upvotes: 1