python sqlite3代码在全局空间中工作,但当我将其放置在函数中时会出错
我试图运行“Python标准库示例”一书中的以下“sqlite3\u custom\u type.py”示例。以下代码是“开箱即用”的:python sqlite3代码在全局空间中工作,但当我将其放置在函数中时会出错,python,sqlite,Python,Sqlite,我试图运行“Python标准库示例”一书中的以下“sqlite3\u custom\u type.py”示例。以下代码是“开箱即用”的: import os import sqlite3 db_filename = 'todo.db' db_is_new = not os.path.exists(db_filename) conn = sqlite3.connect(db_filename) if db_is_new: print('need to create schema'
import os
import sqlite3
db_filename = 'todo.db'
db_is_new = not os.path.exists(db_filename)
conn = sqlite3.connect(db_filename)
if db_is_new:
print('need to create schema')
else:
print('database exists, assume schema does to')
conn.close()
#import sqlite3
try:
import cPickle as pickle
except:
import pickle
db_filename = 'todo.db'
def adapter_func(obj):
"""Convert from in-memory to storage representation.
"""
print 'adapter_func(%s)\n' % obj
return pickle.dumps(obj)
def converter_func(data):
"""Convert from storage to in-memory representation.
"""
print 'converter_func(%r)\n' % data
return pickle.loads(data)
class MyObj(object):
def __init__(self, arg):
self.arg = arg
def __str__(self):
return 'MyObj(%r)' % self.arg
# Register the functions for manipulating the type.
sqlite3.register_adapter(MyObj, adapter_func)
sqlite3.register_converter("MyObj", converter_func)
# Create some objects to save. Use a list of tuples so
# the sequence can be passed directly to executemany().
to_save = [ (MyObj('this is a value to save'),),
(MyObj(42),),
]
with sqlite3.connect(db_filename,
detect_types=sqlite3.PARSE_DECLTYPES) as conn:
# Create a table with column of type "MyObj"
conn.execute("""
create table if not exists obj (
id integer primary key autoincrement not null,
data MyObj
)
""")
cursor = conn.cursor()
# Insert the objects into the database
cursor.executemany("insert into obj (data) values (?)", to_save)
# Query the database for the objects just saved
cursor.execute("select id, data from obj")
for obj_id, obj in cursor.fetchall():
print 'Retrieved', obj_id, obj, type(obj)
print
但是如果我把所有的代码放在一个函数中,比如
def stuff():
~same code as above but indented
if __name__=="__main__":
stuff()
然后我得到一个错误代码:
cursor.executemany("insert into obj (data) values (?)", to_save)
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.
当代码在函数中时,为什么它不工作?我如何使它工作?不要将类和函数放在
stuff
中。特别是,不要把MyObj
放在里面
如果要使用
If.\uuuuu name.\uuuu==“\uuuuu main.\uuuuuu”:
条件,只将不是类或函数的代码放在stuff
中不要将类和函数放在stuff
中。特别是,不要把MyObj
放在里面
如果你想使用
If.\uuuu name.\uuuu==“\uuuu main.\uuuuuu”:
条件,只把不是类或函数的代码放在stuff
中,正如蒂乔德罗马的回答,你需要从stuff
函数中取出所有的类和函数,包括sqlite3.register\u适配器
和sqlite3.register\u转换器
。另外,作为一般的文体观点
以下代码起作用:
import os
import sqlite3
try:
import cPickle as pickle
except:
import pickle
class MyObj(object):
def __init__(self, arg):
self.arg = arg
def __str__(self):
return 'MyObj(%r)' % self.arg
def adapter_func(obj):
"""Convert from in-memory to storage representation.
"""
print('adapter_func(%s)\n' % obj)
return pickle.dumps(obj)
def converter_func(data):
"""Convert from storage to in-memory representation.
"""
print('converter_func(%r)\n' % data)
return pickle.loads(data)
# Register the functions for manipulating the type.
sqlite3.register_adapter(MyObj, adapter_func)
sqlite3.register_converter("MyObj", converter_func)
def stuff():
db_filename = 'todo.db'
db_is_new = not os.path.exists(db_filename)
conn = sqlite3.connect(db_filename)
if db_is_new:
print('need to create schema')
else:
print('database exists, assume schema does to')
conn.close()
db_filename = 'todo.db'
# Create some objects to save. Use a list of tuples so
# the sequence can be passed directly to executemany().
to_save = [ (MyObj('this is a value to save'),),
(MyObj(42),),
]
with sqlite3.connect(db_filename,
detect_types=sqlite3.PARSE_DECLTYPES) as conn:
# Create a table with column of type "MyObj"
conn.execute("""
create table if not exists obj (
id integer primary key autoincrement not null,
data MyObj
)
""")
cursor = conn.cursor()
# Insert the objects into the database
cursor.executemany("insert into obj (data) values (?)", to_save)
# Query the database for the objects just saved
cursor.execute("select id, data from obj")
for obj_id, obj in cursor.fetchall():
print('Retrieved', obj_id, obj, type(obj))
print()
if __name__ == "__main__":
stuff()
根据Tichodroma的回答,您需要从
stuff
函数中取出所有类和函数,包括sqlite3.register\u adapter
和sqlite3.register\u converter
。另外,作为一般的文体观点
以下代码起作用:
import os
import sqlite3
try:
import cPickle as pickle
except:
import pickle
class MyObj(object):
def __init__(self, arg):
self.arg = arg
def __str__(self):
return 'MyObj(%r)' % self.arg
def adapter_func(obj):
"""Convert from in-memory to storage representation.
"""
print('adapter_func(%s)\n' % obj)
return pickle.dumps(obj)
def converter_func(data):
"""Convert from storage to in-memory representation.
"""
print('converter_func(%r)\n' % data)
return pickle.loads(data)
# Register the functions for manipulating the type.
sqlite3.register_adapter(MyObj, adapter_func)
sqlite3.register_converter("MyObj", converter_func)
def stuff():
db_filename = 'todo.db'
db_is_new = not os.path.exists(db_filename)
conn = sqlite3.connect(db_filename)
if db_is_new:
print('need to create schema')
else:
print('database exists, assume schema does to')
conn.close()
db_filename = 'todo.db'
# Create some objects to save. Use a list of tuples so
# the sequence can be passed directly to executemany().
to_save = [ (MyObj('this is a value to save'),),
(MyObj(42),),
]
with sqlite3.connect(db_filename,
detect_types=sqlite3.PARSE_DECLTYPES) as conn:
# Create a table with column of type "MyObj"
conn.execute("""
create table if not exists obj (
id integer primary key autoincrement not null,
data MyObj
)
""")
cursor = conn.cursor()
# Insert the objects into the database
cursor.executemany("insert into obj (data) values (?)", to_save)
# Query the database for the objects just saved
cursor.execute("select id, data from obj")
for obj_id, obj in cursor.fetchall():
print('Retrieved', obj_id, obj, type(obj))
print()
if __name__ == "__main__":
stuff()
根据其他答案,将类放在模块范围内是一种很好的方式。但在这种特殊情况下失败的真正原因是,
pickle.dumps(obj)
调用试图pickle非模块级类
在适配器功能中尝试以下代码:
def adapter_func(obj):
"""Convert from in-memory to storage representation.
"""
try:
return pickle.dumps(obj)
except Exception, arg:
print 'Failed to pickle object [%s]' % arg
当stuff
中声明MyObj
时,您将看到如下错误:
Failed to pickle object [Can't pickle <class '__main__.MyObj'>: it's not found as __main__.MyObj]
未能pickle对象[无法pickle:找不到它作为_umain__;.MyObj]
pickle
要求在模块级别将要pickle的类声明为。sqlite3模块似乎正在挤压适配器函数中引发的异常,而不是通过传播这些异常导致静默故障
您可以在stuff
中声明并注册适配器和转换器函数。除了样式问题,您还可以在函数中声明您的MyObj
,并让它工作,只要您找到其他方法序列化/反序列化对象
这是试图将不在顶层的类进行pickle,这是此问题的根源。根据其他答案,将类放置在模块范围内是一种很好的方式。但在这种特殊情况下失败的真正原因是,pickle.dumps(obj)
调用试图pickle非模块级类
在适配器功能中尝试以下代码:
def adapter_func(obj):
"""Convert from in-memory to storage representation.
"""
try:
return pickle.dumps(obj)
except Exception, arg:
print 'Failed to pickle object [%s]' % arg
当stuff
中声明MyObj
时,您将看到如下错误:
Failed to pickle object [Can't pickle <class '__main__.MyObj'>: it's not found as __main__.MyObj]
未能pickle对象[无法pickle:找不到它作为_umain__;.MyObj]
pickle
要求在模块级别将要pickle的类声明为。sqlite3模块似乎正在挤压适配器函数中引发的异常,而不是通过传播这些异常导致静默故障
您可以在stuff
中声明并注册适配器和转换器函数。除了样式问题,您还可以在函数中声明您的MyObj
,并让它工作,只要您找到其他方法序列化/反序列化对象
试图pickle一个不在顶层的类,这是这个问题的根源。insert语句位于代码的第七行,我使用它来通过一个主类而不是一个方法。它是工作的todo.db是否包含一些表Yettoo.db中没有表。如果在新目录中运行脚本,则会创建一个新的todo.db。try cursor.executemany(“insert into to_save values(??)、to_save)insert语句位于代码的最后第7行,我使用它来通过main中的类而不是方法。它是工作的todo.db是否包含一些表Yettoo.db中没有表。如果我在一个新目录中运行脚本,那么就会创建一个新的todo.db。try cursor.executemany(“插入到to_save values(??)”,to_save)我从stuff中提取了MyObj
、adapter_func
和converter_func
定义,但在同一个位置我仍然得到相同的错误。它确实有效;我需要额外的(很多人会说)建议,把我的import pickle
放在我的任何函数定义之前。我从东西中取出了MyObj
、adapter\u func
和converter\u func
定义,但在同一个地方我仍然得到同样的错误。它确实有效;我需要额外的(很多人会说)建议,将我的import pickle
放在任何函数定义之前。