将巨大的(95Mb)JSON阵列拆分成更小的块?

问题描述 投票:7回答:4

我以JSON的形式从我的数据库中导出了一些数据,基本上只有一个[list],里面有一堆(900K)的{objects}。

现在尝试在我的生产服务器上导入它,但我有一些便宜的Web服务器。当我吃掉所有资源10分钟时,他们不喜欢它。

如何将此文件拆分为较小的块,以便我可以逐个导入它?


编辑:实际上,它是一个PostgreSQL数据库。我对如何以块的形式导出所有数据的其他建议持开放态度。我的服务器上安装了phpPgAdmin,据说可以接受CSV,Tabbed和XML格式。


我不得不修复phihag的脚本:

import json
with open('fixtures/PostalCodes.json','r') as infile:
  o = json.load(infile)
  chunkSize = 50000
  for i in xrange(0, len(o), chunkSize):
    with open('fixtures/postalcodes_' + ('%02d' % (i//chunkSize)) + '.json','w') as outfile:
      json.dump(o[i:i+chunkSize], outfile)

倾倒:

pg_dump -U username -t table database > filename

恢复:

psql -U username < filename

(我不知道什么是pg_restore,但它给了我错误)

有关这方面的教程可以方便地提供这些信息,尤其是-U选项在大多数情况下可能是必要的。是的,手册页解释了这一点,但筛选50个您不关心的选项总是很痛苦。


我最终选择了Kenny的建议......虽然这仍然是一个很大的痛苦。我不得不将表转储到一个文件,压缩它,上传,提取它,然后我尝试导入它,但数据在生产上略有不同,并且有一些丢失的外键(邮政编码附加到城市)。当然,我不能只导入新的城市,因为它会抛出一个重复的键错误,而不是默默地忽略它,这本来是不错的。所以我不得不清空那张桌子,为城市重复这个过程,只是意识到其他东西与城市联系在一起,所以我也必须清空那张桌子。让城市重新进入,最后我可以导入我的邮政编码。到目前为止,我已经删除了一半的数据库,因为一切都与所有内容联系在一起,我不得不重新创建所有条目。可爱。好的我还没有推出这个网站。同样“清空”或截断表似乎没有重置我想要的序列/自动增量,因为有几个魔术条目我想要ID 1.所以..我将不得不删除或重置那些(我不知道怎么做),所以我手动编辑了那些回到1的PK。

我会遇到与phihag解决方案类似的问题,而且我不得不一次导入一个文件,除非我写了另一个导入脚本来匹配导出脚本。虽然他的字面意思确实回答了我的问题,但是谢谢。

python json postgresql ubuntu chunks
4个回答
1
投票

假设您可以选择返回并再次导出数据...:

pg_dump - 将PostgreSQL数据库解压缩到脚本文件或其他存档文件中。

pg_restore - 从pg_dump创建的归档文件中恢复PostgreSQL数据库。

如果这没用,那么知道你将要对输出做什么可能是有用的,这样另一个建议可以达到标记。


8
投票

在Python中:

import json
with open('file.json') as infile:
  o = json.load(infile)
  chunkSize = 1000
  for i in xrange(0, len(o), chunkSize):
    with open('file_' + str(i//chunkSize) + '.json', 'w') as outfile:
      json.dump(o[i:i+chunkSize], outfile)

2
投票

我把phihag和标记的作品变成了tiny script (gist)

还复制如下:

#!/usr/bin/env python 
# based on  http://stackoverflow.com/questions/7052947/split-95mb-json-array-into-smaller-chunks
# usage: python json-split filename.json
# produces multiple filename_0.json of 1.49 MB size

import json
import sys

with open(sys.argv[1],'r') as infile:
    o = json.load(infile)
    chunkSize = 4550
    for i in xrange(0, len(o), chunkSize):
        with open(sys.argv[1] + '_' + str(i//chunkSize) + '.json', 'w') as outfile:
            json.dump(o[i:i+chunkSize], outfile)

1
投票

我知道这是一段时间以来的问题,但我认为这个新的解决方案是无忧无虑的。

您可以使用支持chunksize参数的pandas 0.21.0作为read_json的一部分。您可以一次加载一个块并保存json:

import pandas as pd
chunks = pd.read_json('file.json', lines=True, chunksize = 20)
for i, c in enumerate(chunks):
    c.to_json('chunk_{}.json'.format(i))
© www.soinside.com 2019 - 2024. All rights reserved.