【问题标题】:Python/SQLite storing lists as binaries (blobs)Python/SQLite 将列表存储为二进制文件(blob)
【发布时间】:2012-06-18 20:04:00
【问题描述】:

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

【问题讨论】:

    标签: python sqlite list


    【解决方案1】:

    这个问题似乎与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))
    

    【讨论】:

      猜你喜欢
      • 2021-11-22
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多