Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a "with conn.cursor() as..." way to work with Sqlite?

Instead of using:

import sqlite3
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute(...)
c.close()

would it be possible to use the Pythonic idiom:

with conn.cursor() as c:
    c.execute(...)

It doesn't seem to work:

AttributeError: __exit__

Note: it's important to close a cursor because of this.

like image 303
Basj Avatar asked Nov 25 '18 20:11

Basj


2 Answers

You can use contextlib.closing:

import sqlite3
from contextlib import closing

conn = sqlite3.connect(':memory:')

with closing(conn.cursor()) as cursor:
    cursor.execute(...)

This works because closing(object) automatically calls the close() method of the passed in object after the with block.

like image 143
sudormrfbin Avatar answered Oct 10 '22 02:10

sudormrfbin


A simpler alternative would be to use the connection object with the context manager, as specified in the docs.

with con:
    con.execute(...)

If you insist on working with the cursor (because reasons), then why not make your own wrapper class?

class SafeCursor:
    def __init__(self, connection):
        self.con = connection

    def __enter__(self):
        self.cursor = self.con.cursor()
        return self.cursor

    def __exit__(self, typ, value, traceback):
        self.cursor.close()

You'll then call your class like this:

with SafeCursor(conn) as c:
    c.execute(...)
like image 29
cs95 Avatar answered Oct 10 '22 01:10

cs95