将大(95Mb)JSON数组拆分成小块?

9 投票
4 回答
13045 浏览
提问于 2025-04-16 23:33

我从我的数据库导出了一些数据,格式是JSON,简单来说就是一个包含很多(90万){对象}的[列表]。

现在我想在我的生产服务器上导入这些数据,但我的服务器比较便宜。他们不喜欢我占用他们的资源长达10分钟。

我该如何把这个文件分成小块,以便我可以逐个导入呢?


编辑:其实这是一个PostgreSQL数据库。我也欢迎其他建议,看看如何能把所有数据分块导出。我在服务器上安装了phpPgAdmin,听说它可以接受CSV、制表符和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。

如果我用phihag的解决方案,我也会遇到类似的问题,而且我还得一个一个导入17个文件,除非我写另一个导入脚本来匹配导出脚本。虽然他确实字面上回答了我的问题,所以还是要感谢他。

4 个回答

2

我把phihag和mark的工作变成了一个小脚本 (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)
11

在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)
1

假设你可以重新导出数据……:

pg_dump - 这个命令可以把一个PostgreSQL数据库提取成一个脚本文件或者其他的归档文件。

pg_restore - 这个命令可以从pg_dump创建的归档文件中恢复一个PostgreSQL数据库。

如果这些还不够用,了解你打算如何使用这些输出可能会有帮助,这样我们可以给出更合适的建议。

撰写回答