既に述べたように、SQLite が最初からサポートする型は限られたものだけです。 それ以外の Python の型を SQLite で使うには、その型を sqlite3 モジュールがサポートしている型の一つに 適合 させなくてはなりま せん。サポートしている型というのは、NoneType, int, long, float, str, unicode, buffer です。
sqlite3 モジュールは PEP 246 に述べられているような Python オブジェクト適合を用います。使われるプロトコル は PrepareProtocol です。
sqlite3 モジュールで望みの Python の型をサポートされている型 の一つに適合させる方法は二つあります。
自分でクラスを書いているならばこの方法が良いでしょう。次のようなクラス があるとします:
class Point(object): def __init__(self, x, y): self.x, self.y = x, y
さてこの点を SQLite の一つのカラムに収めたいと考えたとしましょう。最初
にしなければならないのはサポートされている型の中から点を表現するのに使
えるものを選ぶことです。ここでは単純に文字列を使うことにして、座標を区
切るのにはセミコロンを使いましょう。次に必要なのはクラスに変換された値
を返す __conform__(self, protocol)
メソッドを追加することです。
引数 protocol は PrepareProtocol になります。
import sqlite3 class Point(object): def __init__(self, x, y): self.x, self.y = x, y def __conform__(self, protocol): if protocol is sqlite3.PrepareProtocol: return "%f;%f" % (self.x, self.y) con = sqlite3.connect(":memory:") cur = con.cursor() p = Point(4.0, -3.2) cur.execute("select ?", (p,)) print cur.fetchone()[0]
もう一つの可能性は型を文字列表現に変換する関数を作り register_adapter でその関数を登録することです。
import sqlite3 class Point(object): def __init__(self, x, y): self.x, self.y = x, y def adapt_point(point): return "%f;%f" % (point.x, point.y) sqlite3.register_adapter(Point, adapt_point) con = sqlite3.connect(":memory:") cur = con.cursor() p = Point(4.0, -3.2) cur.execute("select ?", (p,)) print cur.fetchone()[0]
sqlite3 モジュールには二つの Python 標準型 datetime.date と datetime.datetime に対するデフォルト適合関数があります。いま datetime.datetime オブジェクトを ISO 表現でなく Unix タイムスタンプ として格納したいとしましょう。
import sqlite3 import datetime, time def adapt_datetime(ts): return time.mktime(ts.timetuple()) sqlite3.register_adapter(datetime.datetime, adapt_datetime) con = sqlite3.connect(":memory:") cur = con.cursor() now = datetime.datetime.now() cur.execute("select ?", (now,)) print cur.fetchone()[0]
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。