pythonsqlitepython-db-api

Connection and cursor still usable outside with block


My system:

A DB connection and a cursor are both considered resources, so that I can use a with clause.

I know that if I open a resource in a with block, it will be automatically closed outside it (files work in this way).

If these assumptions are correct, why can I access a connection or a cursor even from outside the with block?

Try this:

import sqlite3

with sqlite3.connect('test.db') as conn:
    cur = conn.cursor()
    # some code here....


# Now we are outside with block but I can still use conn and cur
cur.execute('''CREATE TABLE IF NOT EXISTS users 
            (name TEST, surname TEXT) ''')
cur2 = conn.cursor() 

Solution

  • The context manager does not close the connection on exit; it either commits the last transaction (if no exception was raised) or rolls it back. From the documentation:

    Note The context manager neither implicitly opens a new transaction nor closes the connection. If you need a closing context manager, consider using contextlib.closing().

    Related, there is no new scope associated with the with statement, so both conn and cur are still in scope following the statement.

    If you want the with statement to close the connection, do as the documentation suggests:

    from contextlib import closing
    
    
    with closing(sqlite3.connect('test.db')) as conn:
        ...