我在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做到这一点吗?
感谢!!!
答案 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()