5

私のテーブルスキーマでは:

... disabled BOOLEAN, ...

データベースに接続する場合:

db = sqlite3.connect(f, detect_types=sqlite3.PARSE_DECLTYPES)
sqlite3.register_converter("BOOLEAN", myfunc)

次のようにレコードを挿入します。

INSERT INTO mytable (disabled, ...) VALUES (:disabled, ...)

disabled: False を含むパラメーター dict と共に。

そのレコードを読み返すと、BOOLEAN 型を変換するために myfunc が呼び出されます。

def myfunc(x):
    print x, type(x)

結果:(0, <type 'str'> もちろん、Falseが必要な場合はTrueと評価されます)

bool を 1 バイトの INTEGER として保存したいのですが、レコードを読み取るときに単純に Python bool に変換したいだけです (コードの他の部分では int ではなく bool が必要です)。SQLite はそれらを文字列として保存していますか、それとも myfunc を呼び出す前に文字列に変換していますか? なんで?

PS - を使用してみsqlite3.register_adapter(bool, int)ましたが、役に立ちませんでした。

4

2 に答える 2

21

2 つの方向にregister_adapterとを組み合わせて使用​​したい場合:register_converter

sqlite3.register_adapter(bool, int)
sqlite3.register_converter("BOOLEAN", lambda v: bool(int(v)))

SQLite は動的型システムを使用しますが、カスタム型の場合0、文字列か整数かを確実に知る方法がないため、ここで文字列を取得します。

または、次を使用します。

sqlite3.register_converter("BOOLEAN", lambda v: v != '0')

これは、レガシー データに関してははるかに柔軟で堅牢ですが、例外を発生させたい場合があります。

デモ:

>>> import sqlite3
>>> db = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES)
>>> sqlite3.register_adapter(bool, int)
>>> sqlite3.register_converter("BOOLEAN", lambda v: bool(int(v)))
>>> db.execute('CREATE TABLE foo (bar BOOLEAN)')
<sqlite3.Cursor object at 0x10a17a340>
>>> db.execute('INSERT INTO foo VALUES (?)', (True,))
<sqlite3.Cursor object at 0x10a17a3b0>
>>> db.execute('INSERT INTO foo VALUES (?)', (False,))
<sqlite3.Cursor object at 0x10a17a340>
>>> for row in db.execute('SELECT * FROM foo'):
...     print row
... 
(True,)
(False,)
于 2013-06-05T10:01:28.320 に答える
2

sqlite3タイプがありません-代わりにbooleanフィールドを として保存してください:integer

>>> import sqlite3
>>> db = sqlite3.connect(':memory:')
>>> db.execute('create table test (col1 integer)')
<sqlite3.Cursor object at 0x3737880>
>>> db.execute('insert into test values (?)', (1,))
<sqlite3.Cursor object at 0x3737960>
>>> print list(db.execute('select * from test'))
[(1,)]

カスタム コンバーター型は、格納された列の文字列表現を取得し、それを使用して新しい型を作成することが期待されます...

次のようなことをした場合:

db = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES)
def myfunc(col):
    val = int(col) == 1
    print val, type(val)
    return val

sqlite3.register_converter('boolean', myfunc)

db.execute('create table blah (something boolean)')
db.executemany('insert into blah values (?)', [(True,), (False,)])
list(db.execute('select * from blah'))

これは私があなたboolが望むと思うものです - ただし、例外を確実に処理する必要があります。そうしないと、例外は黙って抑制されます...

于 2013-06-05T09:52:18.490 に答える