我怎样才能从SQLite查询字典?
db = sqlite.connect("test.sqlite") res = db.execute("select * from table")
通过迭代,我得到了对应的行列表。
for row in res: print row
我可以得到列的名称
col_name_list = [tuple[0] for tuple in res.description]
但是有没有一些function或设置来获得字典,而不是列表?
{'col1': 'value', 'col2': 'value'}
或者我必须自己做?
您可以使用row_factory ,如文档中的示例所示:
import sqlite3 def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d con = sqlite3.connect(":memory:") con.row_factory = dict_factory cur = con.cursor() cur.execute("select 1 as a") print cur.fetchone()["a"]
或者按照文档中的示例之后给出的build议进行操作:
如果返回一个元组不够,而你想要对列进行基于名称的访问,则应该考虑将row_factory设置为高度优化的sqlite3.Rowtypes。 行提供基于索引和不区分大小写的基于名称的访问,几乎没有内存开销。 这可能会比你自己的基于字典的自定义方法或甚至基于db_row的解决scheme更好。
即使使用sqlite3.Row类,您仍然不能使用以下格式的string格式:
print "%(id)i - %(name)s: %(value)s" % row
为了解决这个问题,我使用了一个帮助函数来获取行并将其转换为字典。 当字典对象比Row对象更受欢迎时(例如,Row对象本身不支持字典API的string格式),我只使用它。 但其他时间使用Row对象。
def dict_from_row(row): return dict(zip(row.keys(), row))
从PEP 249 :
Question: How can I construct a dictionary out of the tuples returned by .fetch*(): Answer: There are several existing tools available which provide helpers for this task. Most of them use the approach of using the column names defined in the cursor attribute .description as basis for the keys in the row dictionary. Note that the reason for not extending the DB API specification to also support dictionary return values for the .fetch*() methods is that this approach has several drawbacks: * Some databases don't support case-sensitive column names or auto-convert them to all lowercase or all uppercase characters. * Columns in the result set which are generated by the query (eg using SQL functions) don't map to table column names and databases usually generate names for these columns in a very database specific way. As a result, accessing the columns through dictionary keys varies between databases and makes writing portable code impossible.
所以是的,自己动手吧。
我以为我回答了这个问题,即使答案在Adam Schmideg和Alex Martelli的答案中都有部分提及。 为了像我这样的人有相同的问题,很容易find答案。
conn = sqlite3.connect(":memory:") conn.row_factory = sqlite3.Row#This is the important part, here we are setting row_factory property of connection object to sqlite3.Row(sqlite3.Row is an implementation of row_factory) c = conn.cursor() c.execute('select * from stocks') result = c.fetchall()#returns a list of dictionaries, each item in list(each dictionary) represents a row of the table
或者你可以将sqlite3.Rows转换为字典,如下所示。 这将给一个字典与每行的列表。
def from_sqlite_Row_to_dict(list_with_rows): ''' Turn a list with sqlite3.Row objects into a dictionary''' d ={} # the dictionary to be filled with the row data and to be returned for i, row in enumerate(list_with_rows): # iterate throw the sqlite3.Row objects l = [] # for each Row use a separate list for col in range(0, len(row)): # copy over the row date (ie. column data) to a list l.append(row[col]) d[i] = l # add the list to the dictionary return d
一个通用的select,只用三行
def select_column_and_value(db, sql, parameters=()): execute = db.execute(sql, parameters) fetch = execute.fetchone() return {k[0]: v for k, v in list(zip(execute.description, fetch))} con = sqlite3.connect('/mydatabase.db') c = con.cursor() print(select_column_and_value(c, 'SELECT * FROM things WHERE id=?', (id,)))
但是如果你的查询什么都不返回,会导致错误。 在这种情况下…
def select_column_and_value(self, sql, parameters=()): execute = self.execute(sql, parameters) fetch = execute.fetchone() if fetch is None: return {k[0]: None for k in execute.description} return {k[0]: v for k, v in list(zip(execute.description, fetch))}
要么
def select_column_and_value(self, sql, parameters=()): execute = self.execute(sql, parameters) fetch = execute.fetchone() if fetch is None: return {} return {k[0]: v for k, v in list(zip(execute.description, fetch))}
更短的版本:
db.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])