Sqlite 和 Python -- 使用 fetchone() 返回字典?

30 投票
8 回答
46998 浏览
提问于 2025-04-15 11:20

我在使用Python 2.5中的sqlite3。 我创建了一个看起来像这样的表:

   create table votes (
      bill text,
      senator_id text,
      vote text)

我用类似这样的方式来访问它:

v_cur.execute("select * from votes")
row = v_cur.fetchone()
bill = row[0]
senator_id = row[1]
vote = row[2]

我希望能够让fetchone(或者其他某个方法)返回一个字典,而不是一个列表,这样我就可以通过字段名称来引用数据,而不是通过位置。 比如:

bill = row['bill'] 
senator_id = row['senator_id']
vote = row['vote']

我知道在MySQL中可以做到这一点,但有没有人知道在SQLite中怎么做?

谢谢!!!

8 个回答

11

我最近在使用sqlite3.Row()的时候,想做一些类似的事情。sqlite3.Row()提供了一种像字典那样的接口,或者像元组那样的接口,这个功能很不错,但当我用**kwargs传入行数据时,它却不太好用。所以我需要一个快速的方法把它转换成字典。我发现其实Row()对象可以通过使用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))

在Python 3中,做法更简单:

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

同样,你也可以使用dbCursor.fetchall()命令,把所有的行数据转换成字典列表,这个可以在一个for循环中完成。

77

在sqlite3中其实有一个选项可以做到这一点。你只需要把连接对象中的row_factory成员改成sqlite3.Row

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

或者

conn.row_factory = sqlite3.Row

这样做之后,你就可以像用字典一样,通过名字或者索引来访问行中的元素。这比自己想办法要高效得多。

20

我过去是这样做的:

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

然后你在连接中设置它:

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

这个方法在 pysqlite-2.4.1 和 python 2.5.4 下是有效的。

撰写回答