How to close a SQLAlchemy session?

Following what we commented in How to close sqlalchemy connection in MySQL, I am checking the connections that SQLAlchemy creates into my database and I cannot manage to close them without exiting from Python.

If I run this code in a python console, it keeps the session opened until I exit from python:

from sqlalchemy.orm import sessionmaker
from models import OneTable, get_engine

engine = get_engine(database="mydb")
session = sessionmaker(bind=engine)()

results = session.query(OneTable.company_name).all()

# some work with the data #

session.close()

and the only workaround I found to close it is to call engine.dispose() at the end.

As per the comments in the link I gave above, my question are now:

  • Why is engine.dispose() necessary to close sessions?
  • Doesn't session.close() suffice?

Solution 1:

There's a central confusion here over the word "session". I'm not sure here, but it appears like you may be confusing the SQLAlchemy Session with a MySQL @@session, which refers to the scope of when you first make a connection to MySQL and when you disconnect.

These two concepts are not the same. A SQLAlchemy Session generally represents the scope of one or more transactions, upon a particular database connection.

Therefore, the answer to your question as literally asked, is to call session.close(), that is, "how to properly close a SQLAlchemy session".

However, the rest of your question indicates you'd like some functionality whereby when a particular Session is closed, you'd like the actual DBAPI connection to be closed as well.

What this basically means is that you wish to disable connection pooling. Which as other answers mention, easy enough, use NullPool.

Solution 2:

session.close() will give the connection back to the connection pool of Engine and doesn't close the connection.

engine.dispose() will close all connections of the connection pool.

Engine will not use connection pool if you set poolclass=NullPool. So the connection (SQLAlchemy session) will close directly after session.close().