大型字典列表作为磁盘上的查找表

时间:2014-04-18 07:14:21

标签: python persistence lookup lookup-tables object-persistence

我有一个从API获得的非常大的字典列表(大小的GB)。我想将它用作其他功能的查找表。 Python中有几种对象持久化方法,但是为了便于引用和查找,您建议将哪些字典存储在磁盘上?

{
    "library_id": "7", 
    "set_id": "80344779", 
    "description": "Very long description 1 ...", 
    "value": "1"
  }, 
  {
    "library_id": "22", 
    "set_id": "80344779", 
    "description": "Very long description 2 ...", 
    "value": "1"
  }, 
  {
    "library_id": "24", 
    "set_id": "80344779", 
    "description": "Very long description 3 ...", 
    "value": "8"
  }, 

3 个答案:

答案 0 :(得分:2)

一种方法是创建一个模型(使用Django模型https://docs.djangoproject.com/en/dev/topics/db/models/)类来匹配字典中的字段并将每个字典保存在像

这样的对象中

类似的东西:

from django.db import models

class MyDict(models.model):
    library_id = models.CharField(max_length=30)
    set_id  = models.CharField(max_length=30)
    description = models.CharField(max_length=30)

你可以制作你的" library_id"作为主键,如果它的唯一性将帮助您使用library_id进行查找。

您也可以将Google app-engine的ndb api用于同一目的。 (如果您在Google App引擎上托管)。 https://developers.google.com/appengine/docs/python/ndb/

答案 1 :(得分:1)

您的数据似乎是正常的,即dict键没有变化,对吧?人们可能只是使用像MongoDB这样的基于文档的解决方案,但我认为一个简单的基于SQL的数据库可能更有效并且易于实现。

备选方案是pickle模块(不推荐用于真正的大型对象,因为它们被加载到内存中)或shelve构建在pickle之上,但是对于大文件更有效,afaik(它们不是#39;一次加载到你的记忆中)。搁置的好处是它的语法,它模仿pythons dict-syntax并且应该易于使用(参见链接)。并且不需要设置MongoDB或MySQL数据库(可能会变得复杂,至少在Windows上)。 pickle和shelve都是标准库的一部分。

您还可以查看datasets及其易于使用的界面。它使用了一个sqlite-db。

如果你正在处理大文件(让我们说> 2 GB),我不会坚持使用数据集或搁置,而是使用更成熟的文件,例如sqlalchemy(+ MySQL-DB) )或MongoDB及其Python接口(PyMongo)

答案 2 :(得分:0)

正如其他答案所示,值得研究打包的数据库模型。如果您想要可移植性,可以使用python轻松创建sqlite3数据库。假设您的数据来自API并且只是上面列出的字典元素列表,那么最小工作示例将如下所示:

import sqlite3

# Create a database in memory, in practice you would save to disk
conn = sqlite3.connect(':memory:')

# Read in the data [omitted for brevity]

cmd_create_table='''
CREATE TABLE api_data (
 set_id      INTEGER,
 library_id  INTEGER,
 description STRING,
 value       INTEGER);
CREATE INDEX idx_api ON api_data (library_id, set_id);
'''
conn.executescript(cmd_create_table)

cmd_insert = '''INSERT INTO api_data VALUES (?,?,?,?)'''
keys = ["set_id","library_id","description","value"]

for item in data:
    val = [item[k] for k in keys]
    conn.execute(cmd_insert, val)

def lookup(library_id, set_id):
    cmd_find = 'SELECT * FROM api_data WHERE library_id={} AND set_id={}'
    cmd = cmd_find.format(library_id, set_id)
    return conn.execute(cmd).fetchall()

print lookup(22, 80344779)

>>> [(80344779, 22, u'Very long description 2 ...', 1)]