2013-06-05 175 views
3

在我的表模式:在SQLite數據庫中存儲的bool

... disabled BOOLEAN, ... 

當連接到數據庫:

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

我插入一條記錄,像這樣:

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

隨着參數包含殘疾的字典:錯誤。

當我讀到這個紀錄回,MYFUNC被稱爲布爾類型轉換:

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

結果:0, <type 'str'>(當我想假這當然值爲TRUE)

我想存儲的bool作爲1個字節的INTEGER,我只是想在讀取記錄時將它們轉換爲Python布爾(代碼的其他部分期望bools不是int)。 SQLite將它們存儲爲字符串,還是在調用myfunc之前將它們轉換爲字符串?爲什麼?

P.S. - 我嘗試使用sqlite3.register_adapter(bool, int),無濟於事。

+0

我不知道爲什麼你要回一個字符串,但在將它們轉換,然後爲bool應該是一個解決方法了。 – pypat

回答

12

你想要使用組合register_adapterregister_converter對於兩個方向:

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

SQLite的使用dynamic type system但對於自定義類型它沒有辦法知道肯定,如果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,) 
+0

這在我的應用程序中不起作用。轉換器bool給出一個字符串「0」,其值爲True而不是False。 –

+0

@peuping:你看到我的更新和演示?我正在向你展示它的工作原理。 :-) –

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返回,這是我認爲你想要的 - 但是,你將需要確保處理異常,否則他們會得到默默鎮壓...

+0

這是OP正試圖解決的問題;你可以修改類型。 –

+0

我知道我可以將字符串轉換爲整數。我的問題是爲什麼它給了我一個字符串,而不是一個整數開始。 –