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

时间:2009-05-01 14:19:07

标签: python database sqlite

我在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 个答案:

答案 0 :(得分:73)

在sqlite3中实际上有一个选项。将连接对象的row_factory成员更改为sqlite3.Row

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

conn.row_factory = sqlite3.Row

这将允许您按名称(字典样式)或索引访问行元素。这比创建自己的解决方案更有效。

答案 1 :(得分:18)

过去我这样做的方式:

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。

答案 2 :(得分:9)

我最近在使用sqlite3.Row()时尝试做类似的事情。虽然sqlite3.Row()非常适合提供类似字典的接口或类似接口的元组,但是当我使用** kwargs在行中传输它时它不起作用。因此,需要一种快速将其转换为字典的方法。我意识到只需使用itertools就可以将Row()对象转换为字典。

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循环中的字典列表。

答案 3 :(得分:5)

当然,请将自己设为DictConnection和DictCursor,如http://trac.edgewall.org/pysqlite.org-mirror/wiki/PysqliteFactories中所解释和显示的那样。

答案 4 :(得分:2)

我知道你不是在问这个,但为什么不用sqlalchemy为数据库构建一个orm?那么你可以做点什么,


entry = model.Session.query(model.Votes).first()
print entry.bill, entry.senator_id, entry.vote

作为额外的奖励,您的代码可以轻松移植到备用数据库,连接和诸如此类的东西将免费管理。

答案 5 :(得分:1)

我用过这个:

def get_dict(sql):
    return dict(c.execute(sql,()).fetchall())

然后你可以这样做:

c = conn.cursor()
d = get_dict("select user,city from vals where user like 'a%'");

现在d是一个字典,其中键为user,值为city。这也适用于group by

答案 6 :(得分:0)

我使用这样的东西:

class SqliteRow(object):
    def __init__(self):
        self.fields = []

    def add_field(self, name, value):
        self.fields.append(name)
        setattr(self, name, value)

    def to_tuple(self):
        return tuple([getattr(self, x) for x in self.fields])

与此:

def myobject_factory(cursor, row):
    myobject= MyObject()
    for idx, col in enumerate(cursor.description):
        name, value = (col[0], row[idx])

        myobject.add_field(name, value)
    return myobject

MyObject()是从SqliteRow继承的类。 SqliteRow类是查询要返回的每个对象的基类。 每列都成为一个属性,并登录到fields列表中。 函数to_tuple用于将整个对象更改为适合查询的形式(只需传递整个对象而忘记)。

获取该函数的不同类类型。您需要制作一个工厂对象,该对象将基于字段列表生成对象(例如:带有{some_unique_value_made_of_fields:class}的dict)

这样,我得到一个简单的ORM。

答案 7 :(得分:0)

以下对我有用:

cursor = conn.cursor(buffered = True, dictionary = True)

另一个选择:

cursor = conn.cursor(MySQLdb.cursors.DictCursor)

其余代码:

query = "SELECT * FROM table"
cursor.execute(query)
row = cursor.fetchone()

来源:mysql.connector.cursorMySQLdb.cursors.DictCursor