Python / SQLite将列表存储为二进制文件(blob)

时间:2012-06-18 01:34:21

标签: python sqlite list

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'>

1 个答案:

答案 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))