Python(2系列)とsqlite3でハマった話
Python 2.7.3 + sqlite3で少しハマりました。
col_name
というカラム名を持つtableが存在するsqliteのデータベースファイルsqlite.db
があるとして、以下の様なコードを書くとエラーになります。
from __future__ import unicode_literals import sqlite3 con = sqlite3.connect("./sqlite.db") con.row_factory = sqlite3.Row cur = con.cursor() cur.execute("SELECT * FROM tbl_name") cur.fetchall()["col_name"]
エラーコード
... IndexError: Index must be int or string
怒られている理由は検討つきます。未来からunicode_literals
を持ってきたせいで、keyとしてunicode文字列は使えないのでしょう。
実際に、以下のコードはエラーなく期待した動作をします。
cur.fetchall()["col_name".encode("utf-8")]
いちいちアクセスするたびにencodeを呼び出していたら、なんのためにunicode_literals
を呼び出したのかわかりません。
結果として悪さをしていたのは
con.row_factory = sqlite3.Row
これを、Pythonの公式Docに従って、dict_factory
関数を使うことによって解決出来ました。
def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d ... con.row_factory = dict_factory
エラーをググっても情報が出てこなくて焦りました。やっぱりまず公式リファレンスを見たほうがいいですね。