1. 程式人生 > >Python訪問sqlite3資料庫取得dictionary的正路!

Python訪問sqlite3資料庫取得dictionary的正路!

【引子】

很多人都知道,Python裡是內建了很好用的sqlite3的。但這個庫有個缺陷,在執行fetchall()/fetchone()等方法後,得到的是一個tuple。以前吧,做自己的小專案,tuple就tuple,大不了dump成JsonArray,用的時候就values[index],為了省事,湊合著用。但這次工作需要,咱得返回一個JsonObject,得是字典形式的。

  1. 土方法:自己用迴圈解析tuple,手動轉換成dict,但這方法也太傻了點對吧,還很麻煩,你得自己記住table裡的column鍵,與tuple裡的值拼接。對於SELECT * FROM table還好點,對於

    SELECT column0, column1, ..., FROM table
    簡直煩死。
  2. 一個稍微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))