### 3 SQLite の値を好きな Python 型に変換する

適合関数を書くことで好きな Python 型を SQLite に送り込めるようになりました。 しかし、本当に使い物になるようにするには Python から SQLite さらに Python へという 往還(roundtrip)の変換ができる必要があります。

そこで変換関数(converter)です。

`Point` クラスの例に戻りましょう。x, y 座標をセミコロンで区切った文字列として SQLite に格納したのでした。

まず、文字列を引数として取り `Point` オブジェクトをそれから構築する変換関数 を定義します。

注意: 変換関数は SQLite に送り込んだデータ型に関係なく常に文字列を渡されます。

注意: 変換関数の名前を探す際、大文字と小文字は区別されます。

        def convert_point(s):
            x, y = map(float, s.split(";"))
            return Point(x, y)

次に `sqlite3` モジュールにデータベースから取得したものが本当に点 であることを教えなければなりません。二つの方法があります:

- 宣言された型を通じて暗黙的に
- カラム名を通じて明示的に

どちらの方法も13.13.1節``モジュールの関数と定数''の中で 説明されています。それぞれ `PARSE_DECLTYPES` 定数と `PARSE_COLNAMES` 定数の項目です。

以下の例で両方のアプローチを紹介します。

    import sqlite3

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

        def __repr__(self):
            return "(%f;%f)" % (self.x, self.y)

    def adapt_point(point):
        return "%f;%f" % (point.x, point.y)

    def convert_point(s):
        x, y = map(float, s.split(";"))
        return Point(x, y)

    # Register the adapter
    sqlite3.register_adapter(Point, adapt_point)

    # Register the converter
    sqlite3.register_converter("point", convert_point)

    p = Point(4.0, -3.2)

    #########################
    # 1) Using declared types
    con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
    cur = con.cursor()
    cur.execute("create table test(p point)")

    cur.execute("insert into test(p) values (?)", (p,))
    cur.execute("select p from test")
    print "with declared types:", cur.fetchone()[0]
    cur.close()
    con.close()

    #######################
    # 1) Using column names
    con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
    cur = con.cursor()
    cur.execute("create table test(p)")

    cur.execute("insert into test(p) values (?)", (p,))
    cur.execute('select p as "p [point]" from test')
    print "with column names:", cur.fetchone()[0]
    cur.close()
    con.close()