在我的表架构中:
... disabled BOOLEAN, ...
连接到db:
时db = sqlite3.connect(f, detect_types=sqlite3.PARSE_DECLTYPES)
sqlite3.register_converter("BOOLEAN", myfunc)
我插入一条记录如下:
INSERT INTO mytable (disabled, ...) VALUES (:disabled, ...)
除了包含disabled的参数dict:False。
当我读回该记录时,调用myfunc来转换BOOLEAN类型:
def myfunc(x):
print x, type(x)
结果:0, <type 'str'>
(当我想要假时,当然评估为True)
我希望bool存储为1字节INTEGER,我只是想在读取记录时将它们转换为Python bool(代码的其他部分期望bool不是int)。 SQLite是否将它们存储为字符串,或者在调用myfunc之前将它们转换为字符串?为什么呢?
P.S。 - 我尝试使用sqlite3.register_adapter(bool, int)
,但没有用。
答案 0 :(得分:14)
您希望将register_adapter
和register_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,)
答案 1 :(得分: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
,这是我认为你想要的 - 但是,你需要确保处理异常,否则它们会被默默地压制......