LoginSignup
33
25

More than 5 years have passed since last update.

python + sqlite3でリストを簡単に扱う

Last updated at Posted at 2014-09-12

sqlite3にはリスト型は存在しないため、例えばintegerのリストを格納したい場合はstr()して;(セミコロン)区切りの文字列にjoin()して格納、取り出すときはsplit()してint()するという操作が必要となる。

sqlite3モジュールにはこれらの操作を予め登録し必要に応じて自動で実行する仕組みが存在している。

これによりリスト要素の型が全て一致していることがわかっているのであれば、変換関数をregister_adapter()register_converter()を使って登録することでリストをシームレスに扱うことができる。

以下の例ではtesttableにIntListという型を定義してregister_adapter()register_converter()を使いpythonのデータ型との変換方法を登録している。
connectするときのdetect_types = sqlite3.PARSE_DECLTYPESは必須。

test.py
import sqlite3

CREATE_TABLE = u"""
create table if not exists testtable (
  id      integer primary key,
  intlist IntList
);
"""

IntList = list
sqlite3.register_adapter(IntList, lambda l: ';'.join([str(i) for i in l]))
sqlite3.register_converter("IntList", lambda s: [int(i) for i in s.split(';')])

def main():
    con = sqlite3.connect(":memory:", detect_types = sqlite3.PARSE_DECLTYPES)
    con.row_factory = sqlite3.Row
    con.execute(CREATE_TABLE)

    insert_list = [1,2,3]
    con.execute(u'insert into testtable values(?, ?)', (1, insert_list))
    con.commit()

    cur = con.cursor()
    cur.execute(u'select * from testtable;')
    assert insert_list == cur.fetchone()['intlist']

if __name__ == '__main__':
    main()

register_adapter()register_converter()はユーザ定義の型でももちろん利用可能。
参考: http://docs.python.jp/2/library/sqlite3.html#id6

33
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
25