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

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

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

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

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

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

    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]

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