¿Comprimiendo una serie de objetos JSON mientras se mantiene la lectura en serie?

Tengo un montón de objetos json que necesito comprimir, ya que está consumiendo demasiado espacio en el disco, aproximadamente 20 gigs por valor de unos pocos millones de ellos.

Idealmente, lo que me gustaría hacer es comprimir cada uno individualmente y luego, cuando necesito leerlos, simplemente cargar y descomprimir iterativamente cada uno. Intenté hacer esto creando un archivo de texto con cada línea siendo un objeto json comprimido a través de zlib , pero esto está fallando con una

decompress error due to a truncated stream ,

que creo que es debido a las cadenas comprimidas que contienen nuevas líneas.

Alguien sabe de un buen método para hacer esto?

Simplemente use un objeto gzip.GzipFile() y trátelo como un archivo normal; escriba los objetos JSON línea por línea y léalos línea por línea.

El objeto se encarga de la compresión de forma transparente y almacenará las lecturas en búfer, descomprimiendo los mandriles según sea necesario.

 import gzip import json # writing with gzip.GzipFile(jsonfilename, 'w') as outfile: for obj in objects: outfile.write(json.dumps(obj) + '\n') # reading with gzip.GzipFile(jsonfilename, 'r') as infile: for line in infile: obj = json.loads(line) # process obj 

Esto tiene la ventaja adicional de que el algoritmo de compresión puede hacer uso de la repetición entre objetos para relaciones de compresión.

Es posible que desee probar un analizador json incremental, como jsaone .

Es decir, crea un solo json con todos tus objetos y analízalo como

 with gzip.GzipFile(file_path, 'r') as f_in: for key, val in jsaone.load(f_in): ... 

Esto es bastante similar a la respuesta de Martin, desperdiciando un poco más de espacio pero tal vez un poco más cómodo.

EDIT: oh, por cierto, probablemente sea justo aclarar que escribí jsaone.