2011-08-13 57 views
7

Exporté algunos datos de mi base de datos en forma de JSON, que es esencialmente solo 1 [lista] con un montón (900K) de {objetos} dentro de él.Dividir la matriz JSON de 95mb en trozos más pequeños?

Tratando de importarlo en mi servidor de producción ahora, pero tengo un servidor web barato. No les gusta cuando como todos sus recursos durante 10 minutos.

¿Cómo puedo dividir este archivo en trozos más pequeños para poder importarlo pieza por pieza?


Editar: En realidad, es una base de datos PostgreSQL. Estoy abierto a otras sugerencias sobre cómo puedo exportar todos los datos en fragmentos. Tengo phpPgAdmin instalado en mi servidor, que supuestamente puede aceptar formatos CSV, Tabbed y XML.


que tenía que corregir el guión de 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) 

volcado:

pg_dump -U username -t table database > filename 

de restauración:

psql -U username < filename 

(I don' t saber qué diablos hace pg_restore, pero me da errores)

Los tutoriales sobre esto dejan convenientemente esta información, esp. la opción -U que probablemente sea necesaria en la mayoría de los casos. Sí, las páginas del manual explican esto, pero siempre es difícil analizar 50 opciones que no te importan.


Terminé yendo con la sugerencia de Kenny ... aunque todavía era un gran dolor. Tuve que volcar la tabla en un archivo, comprimirlo, cargarlo, extraerlo, luego traté de importarlo, pero los datos eran ligeramente diferentes en la producción y faltaban algunas claves externas (los códigos postales están adjuntos a las ciudades). Por supuesto, no podía simplemente importar las nuevas ciudades, porque arroja un error de clave duplicada en lugar de ignorarlo silenciosamente, lo que hubiera sido agradable. Así que tuve que vaciar esa mesa, repetir el proceso para las ciudades, solo para darme cuenta de que algo más estaba vinculado a las ciudades, así que también tuve que vaciar esa mesa. Recuperé las ciudades, y finalmente pude importar mis códigos postales. Ahora borré la mitad de mi base de datos porque todo está ligado a todo y tuve que recrear todas las entradas. Encantador. Menos mal que aún no lancé el sitio. También "vaciar" o truncar una tabla no parece restablecer las secuencias/autoincrementos, lo que me gustaría, porque hay un par de entradas mágicas, quiero tener ID 1. Entonces ... tendría que eliminar o restablecer esos también (no sé cómo), así que edité manualmente los PK para aquellos de nuevo a 1.

Hubiera encontrado problemas similares con la solución de phihag, además habría tenido que importar 17 archivos, uno a hora, a menos que haya escrito otro script de importación para que coincida con el script de exportación. Aunque contestó mi pregunta literalmente, así que gracias.

Respuesta

1

Asumiendo que tienen la opción de volver atrás y exportar los datos de nuevo ...:

pg_dump - extrae una base de datos PostgreSQL en un archivo de script u otro archivo de almacenamiento.

pg_restore - restaurar una base de datos PostgreSQL de un archivo de almacenamiento creado por pg_dump.

Si eso no sirve, podría ser útil saber qué va a hacer con la salida para que otra sugerencia pueda dar en el blanco.

+0

pg_dump estaría bien ... pero la restauración probablemente consumiría demasiados recursos si no está en pedazos. Todo lo que estoy haciendo con la salida es importarlo en mi servidor de producción. – mpen

+0

Ahora estoy para adivinar el territorio, pero habría pensado que la alta utilización de recursos en el método JSON tendría que ver con el análisis JSON. Pero como digo, eso es una total conjetura. Probaría el método pg_dump y pg_restore para ver qué sucedió (mientras veía los recursos, por supuesto;)) – Kenny

+0

Parece que (probablemente ya sea obvio que no he usado Postgres antes): --data-only Vierta solo los datos, no el esquema (definiciones de datos). – Kenny

7

En 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) 
+0

Me estoy poniendo 'AttributeError: objeto 'str' no tiene atributo '__exit __' 'en la línea "con". Nvm, lo descubrió. ¡Muchas gracias! – mpen

+0

@Mark oops, olvidé un 'abierto'. Fijo. – phihag

2

que resultó de phihag y el trabajo de la marca en un tiny script (gist)

también copiado a continuación:

#!/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

Sé que esto es pregunta es desde hace un tiempo, pero creo que esta nueva solución se realiza sin problemas.

Puede usar pandas 0.21.0 que admita un parámetro de tamaño completo como parte de read_json. Puede cargar un trozo a la vez y guardar el 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)) 
Cuestiones relacionadas