【引子】
很多人都知道,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))