Sqlite and Python -- return a dictionary using fetchone()?

The way I've done this in the past:

def dict_factory(cursor, row):
    d = {}
    for idx,col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

Then you set it up in your connection:

from pysqlite2 import dbapi2 as sqlite
conn = sqlite.connect(...)
conn.row_factory = dict_factory

This works under pysqlite-2.4.1 and python 2.5.4.


I was recently trying to do something similar while using sqlite3.Row(). While sqlite3.Row() is great for providing a dictionary-like interface or a tuple like interface, it didn't work when I piped in the row using **kwargs. So, needed a quick way of converting it to a dictionary. I realised that the Row() object can be converted to a dictionary simply by using itertools.

Python 2:

db.row_factory = sqlite3.Row
dbCursor = db.cursor()
dbCursor.execute("SELECT * FROM table")
row = dbCursor.fetchone()

rowDict = dict(itertools.izip(row.keys(), row))

Or in Python 3, more simply:

dbCursor = db.cursor()
dbCursor.execute("SELECT * FROM table")
row = dbCursor.fetchone()
rowDict = dict(zip([c[0] for c in dbCursor.description], row))

Similarly, you can use the dbCursor.fetchall() command and convert the entire set of rows to a list of dictionaries in a for loop.


There is actually an option for this in sqlite3. Change the row_factory member of the connection object to sqlite3.Row:

conn = sqlite3.connect('db', row_factory=sqlite3.Row)

or

conn.row_factory = sqlite3.Row

This will allow you to access row elements by name--dictionary-style--or by index. This is much more efficient than creating your own work-around.