如何从 sqlite 查询中获取 dict?
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'}
还是我必须自己做?
db = sqlite.connect("test.sqlite")
res = db.execute("select * from table")
With iteration I get lists coresponding to the rows.
for row in res:
print row
I can get name of the columns
col_name_list = [tuple[0] for tuple in res.description]
But is there some function or setting to get dictionaries instead of list?
{'col1': 'value', 'col2': 'value'}
or I have to do myself?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
您可以使用 row_factory,如文档中的示例所示:
或者遵循文档中此示例之后给出的建议:
这是第二个解决方案的代码:
You could use row_factory, as in the example in the docs:
or follow the advice that's given right after this example in the docs:
Here is the code for this second solution:
我想我回答了这个问题,尽管 Adam Schmideg 和 Alex Martelli 的答案中都部分提到了这个问题。为了让和我有同样疑问的人能够轻松找到答案。
I thought I answer this question even though the answer is partly mentioned in both Adam Schmideg's and Alex Martelli's answers. In order for others like me that have the same question, to find the answer easily.
连接到 SQLite 后:
con = sqlite3.connect(.....)
只需运行即可:瞧!
After you connect to SQLite:
con = sqlite3.connect(.....)
it is sufficient to just run:Voila!
即使使用 sqlite3.Row 类,您仍然不能使用以下形式的字符串格式:
为了解决这个问题,我使用一个辅助函数来获取行并转换为字典。我只在字典对象优于 Row 对象时才使用它(例如,对于字符串格式化之类的事情,其中 Row 对象本身也不支持字典 API)。但其他时候都使用 Row 对象。
Even using the sqlite3.Row class-- you still can't use string formatting in the form of:
In order to get past this, I use a helper function that takes the row and converts to a dictionary. I only use this when the dictionary object is preferable to the Row object (e.g. for things like string formatting where the Row object doesn't natively support the dictionary API as well). But use the Row object all other times.
正如 @gandalf 的回答所提到的,必须使用 conn.row_factory = sqlite3.Row,但结果不是直接的字典。必须在最后一个循环中向 dict 添加额外的“转换”:
As mentioned by @gandalf's answer, one has to use
conn.row_factory = sqlite3.Row
, but the results are not directly dictionaries. One has to add an additional "cast" todict
in the last loop:来自 PEP 249:
所以是的,你自己做吧。
From PEP 249:
So yes, do it yourself.
较短的版本:
Shorter version:
我的测试中最快:
vs:
你决定:)
Fastest on my tests:
vs:
You decide :)
与前面提到的解决方案类似,但最紧凑:
Similar like before-mentioned solutions, but most compact:
获取查询结果
选项 1)带 Zip 的显式循环
选项 2)带 Dict Comp 的更快循环
Get the results of the query
Option 1) Explicit Loop w/ Zip
Option 2) Faster Loop w/ Dict Comp
我认为你走在正确的道路上。让我们保持这个非常简单并完成您想要做的事情:
缺点是
.fetchall()
,如果您的表非常多,它会严重消耗您的内存大的。但对于仅处理几千行文本和数字列的琐碎应用程序,这种简单的方法就足够了。对于严肃的事情,您应该研究行工厂,正如许多其他答案中所建议的那样。
I think you were on the right track. Let's keep this very simple and complete what you were trying to do:
The downside is that
.fetchall()
, which is murder on your memory consumption, if your table is very large. But for trivial applications dealing with mere few thousands of rows of text and numeric columns, this simple approach is good enough.For serious stuff, you should look into row factories, as proposed in many other answers.
或者您可以将 sqlite3.Rows 转换为字典,如下所示。这将给出一个字典,其中每行都有一个列表。
Or you could convert the sqlite3.Rows to a dictionary as follows. This will give a dictionary with a list for each row.
一个通用的替代方案,仅使用三行
,但如果您的查询不返回任何内容,将导致错误。在这种情况下...
或者
A generic alternative, using just three lines
But if your query returns nothing, will result in error. In this case...
or
结果肯定是真的,但我不知道最好的。
The result is definitely true, but I do not know the best.
python 中的字典提供对其元素的任意访问。
因此,任何带有“名称”的字典虽然一方面可能提供信息(又名字段名称是什么),但会“取消排序”字段,这可能是不需要的。
最好的方法是将名称放在单独的列表中,然后根据需要自行将它们与结果组合起来。
另请记住,在所有方法中,名称都是您在查询中提供的名称,而不是数据库中的名称。例外是
SELECT * FROM
如果您唯一关心的是使用字典获取结果,那么一定要使用
conn.row_factory = sqlite3.Row
(已在另一个答案中说明) )。Dictionaries in python provide arbitrary access to their elements.
So any dictionary with "names" although it might be informative on one hand (a.k.a. what are the field names) "un-orders" the fields, which might be unwanted.
Best approach is to get the names in a separate list and then combine them with the results by yourself, if needed.
Also remember that the names, in all approaches, are the names you provided in the query, not the names in database. Exception is the
SELECT * FROM
If your only concern is to get the results using a dictionary, then definitely use the
conn.row_factory = sqlite3.Row
(already stated in another answer).我将把我的错误代码留在这里
i'll just leave my bad code here