sqlite的官方文档建议将列表存储为二进制对象。谷歌引导我提出各种建议。一个是使用数组模块(array.array('B',my_list2),但这对于一个非平凡的列表不起作用:
my_list2 = [(23,"Bob"), (22,"Alice")]
array.array('B',my_list2)
TypeError: an integer is required
另一个建议涉及使用泡菜,但有人插话声称它不安全。最后一个建议是为每个列表变量创建一个新表,其中有几个。我现在对制作复杂的架构犹豫不决。
我该怎么办?我应该如何将my_list2以及其他列表存储在数据库中?
修改
找到一个优雅而整洁的解决方案,适用于简单和复杂的案例,只需最少的代码:
import json
my_list2 = [(23,"Bob Baker"), (22,"Alice Adams")]
my_list2_str = json.dumps(my_list2)
print type(my_list2_str)
<type 'str'>
list2 = json.loads(my_list2_str)
print list2, type(list2)
[(23, u"Bob Baker"), (22, u"Alice Adams")] <type 'list'>
答案 0 :(得分:3)
这个问题似乎与this earlier SO question非常相似,所以一开始我认为这可能会解决您的问题。但是再看一下你的问题,似乎你确实读过这个问题,因为你提到了他们提出的两种方法。此外,由于您的数据类型不同(元组列表而不是整数列表),我将给您一个通行证。
进行一些研究我发现许多使用方法sqlite3.Binary()
的代码示例(例如here)。这可能是你想要的,但令我担心的是我可以在Sqlite3 Python Interface API找到绝对没有文档这个功能。因此,我建议不要使用它。我猜这个方法已被弃用,但我找不到任何有关替换它的明确文档。
也就是说,如果您阅读Sqlite3 Python Interface API,您会看到它自动将BLOB转换为python buffer对象(以及缓冲区对象为BLOB)。因此在我看来,如果你可以将列表转换为缓冲区,那么你可以将它作为BLOB轻松存储。
在我的研究中,我发现列表不能存储为缓冲区。我还发现虽然有将列表转换为缓冲区的方法,但它们需要简单类型的列表(即不是元组)。因此,我认为最好的办法是定义一些实用工具方法,用于将列表转换为字符串和从字符串转换,然后将字符串转换为缓冲区(当您从数据库中检索它们时返回)。
def myListToStr(myList):
"""This method takes a list of (int, str) tuples and converts them to a string"""
strList = ""
for item in myList:
num, name = item #split the tuple
strList += "{}:{} ".format(num, name) #append the tuple in "num:name" format with a " " delimiter
return strList[:-1] #remove the final space (unneeded)
def strToMyList(myStr):
"""This method takes a string in the format "int:str int:str int:str..."
and converts it to a list of (int, str) tuples"""
myList = []
for tup in myStr.split(" "): #for each converted tuple
numStr, name = tup.split(":") #split the tuple
num = int(numStr) #NOTE: this will throw an error if numStr.isdigit() is False
myList.append(num, name)
return myList
现在,转换为缓冲区就像
一样简单my_list2Buff = buffer(myListToStr(my_list2))
然后回来......
my_list2 = strToList(str(my_list2Buff))