Python访问sqlite3数据库取得dictionary的正路!
【引子】
很多人都知道,Python里是内置了很好用的sqlite3的。但这个库有个缺陷,在执行fetchall()/fetchone()等方法后,得到的是一个tuple。以前吧,做自己的小项目,tuple就tuple,大不了dump成JsonArray,用的时候就values[index],为了省事,凑合着用。但这次工作需要,咱得返回一个JsonObject,得是字典形式的。
-
土方法:自己用循环解析tuple,手动转换成dict,但这方法也太傻了点对吧,还很麻烦,你得自己记住table里的column键,与tuple里的值拼接。对于SELECT * FROM table还好点,对于
SELECT column0, column1, ..., FROM table
简直烦死。 -
一个稍微Py点的写法是这样的:
values = [{'id' : row[0], 'name' : row[1]} for row in con.fetchall()]
不错,看起来高大上多了,有python范。但要只是仅此而已的话,me是不屑专门写篇博文来记录滴!
【正文】
首先呢,我们知道,python访问MySql时有个不错的方法:
cursor=db.cursor(MySQLdb.cursors.DictCursor)(不知道?那算你看此文的额外收获)。那么类似的,sqlite3里有没有这样的实现呢?很遗憾,目前我没发现,不然也轮不到我这篇博文来讨论这个问题了。但,没有这样的实现,不代表不能实现!查Api,官方其实是预留了实现方案的!connect其实有一个属性,con.row_factory!看到名字估计很多人瞬间就有想法了对吧?没错,甚至Api里都已经写好了一个实现的函数:
def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d
只要简单的把这个函数传递给con.row_factory就ok了,以后从这个con取出的值就会通过这个函数,变成key:value形式,key就是创建table时指定的column名字,你再也不用另行记录它们,因为它们本就是存在的,cursor.description本就包含这个信息,只是默认没有被添加到结果里罢了!
呃,上面那个是官方Api里面给出的,其实还有更加Pythonic的写法:
def dict_factory(cursor, row): return dict((col[0], row[idx]) for idx, col in enumerate(cursor.description))
爱冷剑,怜悲箫,月下狼孤啸;
轻点画,慢勾描,云中人逍遥。