Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sqlalchemy mysql connections not closing on flask api

I have an api I have written in flask. It uses sqlalchemy in order to deal with a mysql database. I don't use flask-sqlalchemy, because I don't like the way that the module forces you into a certain pattern for declaring the model.

I'm having a problem in which my database connections are not closing. The object representing the connection is going out of scope, so I assume it is being garbage collected. I also explicitly call close() on the session. Despite these facts, the connections stay open long after the api call has returned its response.

sqlsession.py: Here is the wrapper I am using for the session.

class SqlSession:
    def __init__(self, conn=Constants.Sql):
        self.db = SqlSession.createEngine(conn)

        Session = sessionmaker(bind=self.db)
        self.session = Session()
    @staticmethod
    def createEngine(conn):
        return create_engine(conn.URI.format(user=conn.USER, password=conn.PASS, host=conn.HOST, port=conn.PORT, database=conn.DATABASE, poolclass=NullPool))

    def close(self):
        self.session.close()

flaskroutes.py: Here is an example of the flask app instantiating and using the wrapper object. Note that it instantiates it in the beginning within the scope of the api call, then closes the session at the end, and presumably is garbage collected after the response is returned.

def commands(self, deviceId):
    sqlSession = SqlSession(self.sessionType) <---

    commandsQueued = getCommands()
    jsonCommands = []
    for command in commandsQueued:
     jsonCommand = command.returnJsonObject()
     jsonCommands.append(jsonCommand)
     sqlSession.session.delete(command)
    sqlSession.session.commit()
    resp = jsonify({'commands': jsonCommands})
    sqlSession.close() <---  
    resp.status_code = 200
    return resp

I would expect the connections to be cleared as soon as the http response is made, but instead the connections end up with the "SLEEP" state (when viewed in the mysql command line interface 'show processlist').

like image 211
melchoir55 Avatar asked Mar 14 '15 06:03

melchoir55


People also ask

Does SQLAlchemy close connection automatically?

close() method is automatically invoked at the end of the block. The Connection , is a proxy object for an actual DBAPI connection.

How do I close a Flask-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. and the only workaround I found to close it is to call engine. dispose() at the end.

How do I close SQLAlchemy connection in Python?

you call close(), as documented. dispose() is not needed and in fact calling dispose() explicitly is virtually never needed for normal SQLAlchemy usage.

How does SQLAlchemy connect to Flask?

Step 1 - Install the Flask-SQLAlchemy extension. Step 2 - You need to import the SQLAlchemy class from this module. Step 3 - Now create a Flask application object and set the URI for the database to use. Step 4 - then use the application object as a parameter to create an object of class SQLAlchemy.


1 Answers

I ended up using the advice from this SO post: How to close sqlalchemy connection in MySQL

I strongly recommend reading that post to anyone having this problem. Basically, I added a dispose() call to the close method. Doing so causes the entire connection to be destroyed, while closing simply returns connections to an available pool (but leave them open).

def close(self):
    self.session.close()
    self.db.dispose()

This whole this was a bit confusing to me, but at least now I understand more about the connection pool.

like image 88
melchoir55 Avatar answered Oct 15 '22 11:10

melchoir55