1

I have this proxy class for SQLAlchemy Session:

class MySqlSession(object):
    def __init__(self):
        self.sql_session = DBSession()

    def close(self):
        if self._closed:
            return
        self._closed = True
        self._session.rollback()
        self._session.close()

    def __del__(delf):
        self.close()

DBSession is created by

DBSession = sessionmaker(bind=engine, autoflush=True, expire_on_commit=True)

and I receive exception: sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) Cannot operate on a closed database. on self._session.rollback() line when __del__ is called, but all queries to object, which received from self._session before __del__ calling is success.

How can I solve this problem?

COUNTERKILL
  • 173
  • 10
  • 1
    How are you using this? `__del__` is only called when your object's reference count is reduced to zero - so if `close` has been called somewhere prior to that, when the object is garbage collected, you're trying to close a closed connection... – Jon Clements Oct 26 '17 at 08:09
  • Therefore i have check `if self._closed: return`. I use proxy object such as: ```session = MySqlSession() # some queries session = None``` – COUNTERKILL Oct 26 '17 at 08:11
  • 1
    Or... don't implement a `__del__` and just let the session object clear itself up which'll involve checking the connection is closed and any pending transactions are cancelled... – Jon Clements Oct 26 '17 at 08:13
  • But does it lead to the rollback itself withowt calling session.rollback() manually? – COUNTERKILL Oct 26 '17 at 08:16
  • 1
    Why are you hiding the rollback in close to begin with? Closing a session [does implicitly rollback the transactional state of a connection](https://stackoverflow.com/questions/46802739/does-closing-a-sqlalchemy-orm-session-roll-back-uncommitted-changes/46803458#46803458), but you [should still explicitly rollback](https://stackoverflow.com/questions/17008441/why-do-sqlalchemy-session-close-not-log-rollback/17013336#17013336) a session. A much better way would be to create a context manager for use in a with-statement. Also provide a [mcve]. – Ilja Everilä Oct 26 '17 at 08:21

0 Answers0