Mel*_*oun 98 python sql sqlite dictionary dataformat
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]
但是有一些功能或设置来获取字典而不是列表吗?
{'col1': 'value', 'col2': 'value'}
或者我必须自己做?
Ale*_*lli 141
您可以使用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"]
或遵循文档中此示例后给出的建议:
如果返回一个元组是不够的,并且您希望对列进行基于名称的访问,则应考虑将row_factory设置为高度优化的sqlite3.Row类型.Row提供基于索引和不区分大小写的基于名称的访问,几乎没有内存开销.它可能比您自己的基于字典的自定义方法甚至基于db_row的解决方案更好.
gan*_*alf 22
尽管在Adam Schmideg和Alex Martelli的回答中都部分提到了答案,但我还是回答了这个问题.为了让像我这样有其他问题的人能够轻松找到答案.
conn = sqlite3.connect(":memory:")
#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)
conn.row_factory = sqlite3.Row
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
bbe*_*ort 19
即使使用sqlite3.Row类 - 您仍然不能以下列形式使用字符串格式:
print "%(id)i - %(name)s: %(value)s" % row
为了解决这个问题,我使用一个辅助函数来获取行并转换为字典.我只在字典对象优于Row对象时才使用它(例如,对于字符串格式化,其中Row对象本身也不支持字典API).但是所有其他时间都使用Row对象.
def dict_from_row(row):
    return dict(zip(row.keys(), row))       
Luk*_*ski 14
连接到 SQLite 后:
con = sqlite3.connect(.....)只需运行:
con.row_factory = sqlite3.Row
瞧!
Bas*_*asj 11
正如 @gandalf 的回答所提到的,必须使用conn.row_factory = sqlite3.Row,但结果不是直接的字典。必须dict在最后一个循环中添加额外的“转换”:
import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute('create table t (a text, b text, c text)')
conn.execute('insert into t values ("aaa", "bbb", "ccc")')
conn.execute('insert into t values ("AAA", "BBB", "CCC")')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from t')
for r in c.fetchall():
    print(dict(r))
# {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
# {'a': 'AAA', 'b': 'BBB', 'c': 'CCC'}
从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
     (e.g.  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.
所以,是的,自己动手吧.
较短的版本:
db.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
我的测试中最快:
\n\nconn.row_factory = lambda c, r: dict(zip([col[0] for col in c.description], r))\nc = conn.cursor()\n\n%timeit c.execute('SELECT * FROM table').fetchall()\n19.8 \xc2\xb5s \xc2\xb1 1.05 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n对比:
\n\nconn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])\nc = conn.cursor()\n\n%timeit c.execute('SELECT * FROM table').fetchall()\n19.4 \xc2\xb5s \xc2\xb1 75.6 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100000 loops each)\n你决定 :)
\n与前面提到的解决方案类似,但最紧凑:
db.row_factory = lambda C, R: { c[0]: R[i] for i, c in enumerate(C.description) }
| 归档时间: | 
 | 
| 查看次数: | 86488 次 | 
| 最近记录: |