Subsections

13.13.4.2 追加された Python の型を SQLite データベースに格納するために適合関数を使う

既に述べたように、SQLite が最初からサポートする型は限られたものだけです。 それ以外の Python の型を SQLite で使うには、その型を sqlite3 モジュールがサポートしている型の一つに 適合 させなくてはなりま せん。サポートしている型というのは、NoneType, int, long, float, str, unicode, buffer です。

sqlite3 モジュールは PEP 246 に述べられているような Python オブジェクト適合を用います。使われるプロトコル は PrepareProtocol です。

sqlite3 モジュールで望みの Python の型をサポートされている型 の一つに適合させる方法は二つあります。

13.13.4.2.1 オブジェクト自身で適合するようにする

自分でクラスを書いているならばこの方法が良いでしょう。次のようなクラス があるとします:

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

さてこの点を SQLite の一つのカラムに収めたいと考えたとしましょう。最初 にしなければならないのはサポートされている型の中から点を表現するのに使 えるものを選ぶことです。ここでは単純に文字列を使うことにして、座標を区 切るのにはセミコロンを使いましょう。次に必要なのはクラスに変換された値 を返す __conform__(self, protocol) メソッドを追加することです。 引数 protocolPrepareProtocol になります。

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]

13.13.4.2.2 適合関数を登録する

もう一つの可能性は型を文字列表現に変換する関数を作り register_adapter でその関数を登録することです。

注意: 適合させる型/クラスは新形式クラスでなければなりません。すなわち、object を基底クラスの一つとしていなければなりません。

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.datedatetime.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]

ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。