Sqlite and Python — return a dictionary using fetchone()?
我正在python 2.5中使用sqlite3。我创建了一个看起来像这样的表:
1 2 3 4 | create table votes ( bill text, senator_id text, vote text) |
我正在使用类似这样的内容进行访问:
1 2 3 4 5 | v_cur.execute("select * from votes") row = v_cur.fetchone() bill = row[0] senator_id = row[1] vote = row[2] |
我想做的是让fetchone(或其他方法)返回字典,而不是列表,以便我可以按名称而不是位置来引用该字段。例如:
1 2 3 | bill = row['bill'] senator_id = row['senator_id'] vote = row['vote'] |
我知道您可以使用MySQL执行此操作,但是有人知道如何使用SQLite进行操作吗?
谢谢!!!
在sqlite3中实际上有一个选项。将连接对象的
1 | conn = sqlite3.connect('db', row_factory=sqlite3.Row) |
或
1 | conn.row_factory = sqlite3.Row |
这将允许您按名称(字典样式)或按索引访问行元素。这比创建自己的解决方法要有效得多。
我过去这样做的方式:
1 2 3 4 5 | def dict_factory(cursor, row): d = {} for idx,col in enumerate(cursor.description): d[col[0]] = row[idx] return d |
然后您在连接中进行设置:
1 2 3 | from pysqlite2 import dbapi2 as sqlite conn = sqlite.connect(...) conn.row_factory = dict_factory |
这在pysqlite-2.4.1和python 2.5.4下有效。
我最近在尝试使用sqlite3.Row()时做类似的事情。虽然sqlite3.Row()非常适合提供类似于字典的接口或类似于元组的接口,但是当我使用** kwargs在行中进行管道传输时,它不起作用。因此,需要一种将其转换为字典的快速方法。我意识到,只需使用itertools,就可以将Row()对象转换为字典。
Python 2:
1 2 3 4 5 6 | 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中更简单:
1 2 3 4 | 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循环中的词典列表。
当然,请按照http://trac.edgewall.org/pysqlite.org-mirror/wiki/PysqliteFactories中的说明和说明,使自己成为DictConnection和DictCursor。
我知道您不是在问这个问题,但是为什么不仅仅使用sqlalchemy为数据库建立一个orm?那么你可以做类似的事情,
1 2 | entry = model.Session.query(model.Votes).first() print entry.bill, entry.senator_id, entry.vote |
作为一项额外的奖励,您的代码将可以轻松地移植到备用数据库中,并且免费管理连接和其他内容。
简单的解决方案,初始化一个游标对象:
1 | cursor = conn.cursor(buffered = True, dictionary = True) |
另一个选项:
1 | cursor = conn.cursor(MySQLdb.cursors.DictCursor) |
其余代码:
1 2 3 | query ="SELECT * FROM table" cursor.execute(query) row = cursor.fetchone() |
来源:mysql.connector.cursor,MySQLdb.cursors.DictCursor
我已经使用过:
1 2 | def get_dict(sql): return dict(c.execute(sql,()).fetchall()) |
然后您可以执行以下操作:
1 2 | c = conn.cursor() d = get_dict("select user,city from vals where user like 'a%'"); |
现在
我使用类似这样的东西:
1 2 3 4 5 6 7 8 9 10 | 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]) |
与此:
1 2 3 4 5 6 7 | 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 |
SqliteRow类是查询要返回的每个对象的基类。
每列都将成为一个属性,并记录到
函数
获取该函数的不同类类型。您需要创建一个工厂对象,该工厂对象将基于字段列表生成对象(例如:带有{some_unique_value_made_of_fields:class}的dict)
这样,我得到一个简单的ORM。