es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo leer un archivo JSON que contiene múltiples diccionarios con boto3.

Tengo varios archivos JSON que contienen múltiples diccionarios almacenados en S3. Necesito acceder a cada línea y cambiar el nombre de algunas de las claves. He escrito el código en mi entorno local, el cual funciona perfectamente, pero tengo problemas al usar Lambda. Por lo general, obtengo un error “Expecting property name enclosed in double quotes” (Esperando que el nombre de la propiedad esté entre comillas dobles).

JSON de ejemplo:

{
  "request": 123,
  "key1": [
    {
      "timestamp_unix": 98321,
      "key_2": "Portugal"
    }
  ]
}
{
  "request": 456,
  "key1": [
    {
      "timestamp_unix": 35765,
      "key_2": "China"
    }
  ]
}

Código local:

import json

with open("myfile.json", "r") as f:
    my_file = [json.loads(line) for line in f]
for j in my_file:
    j[key1][0][key2] = j[key1][0].pop("key_2")

Código AWS:

import boto3
import json

s3 = boto3.resource("s3")

obj = s3.Object("my-bucket", "path_to/myfile.json")
json_string = obj.get()["Body"].read().decode("utf-8") # aquí es donde se lee el objeto JSON con comillas simples en lugar de comillas dobles
my_file = [json.loads(line) for line in json_string] # error, error, error

También intenté:

import boto3
import json

s3_client = boto3.client("s3")

obj = s3_client.get_object(Bucket="my-bucket", Key="path_to/myfile.json")
json_string = obj["Body"].read().decode() # aquí es donde se lee el objeto JSON con comillas simples en lugar de comillas dobles
my_file = [json.loads(line) for line in json_string] # error, error, error

También probé eliminar por completo la opción encode(), pero esto tampoco funcionó. No quiero/no puedo cambiar los archivos JSON subyacentes y almacenar los diccionarios en una lista.

¿Cómo puedo leer archivos JSON con múltiples diccionarios utilizando boto3?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema con el código proporcionado es que el archivo JSON se está leyendo como una cadena y luego se intenta cargar utilizando json.loads(), que espera una cadena con comillas dobles tanto para las claves como para los valores. Sin embargo, en el archivo JSON proporcionado, las claves y los valores están encerrados en comillas simples.

    Para resolver este problema, podemos modificar el código para utilizar un analizador JSON que también pueda manejar comillas simples. Un analizador de este tipo es demjson, que se puede instalar utilizando pip install demjson. Así es como se puede modificar el código para usar demjson:

    import boto3
    import demjson
    
    s3 = boto3.resource("s3")
    
    obj = s3.Object("mi-bucket", "ruta_a/miarchivo.json")
    cadena_json = obj.get()["Body"].read().decode("utf-8")
    
    # utilizar demjson para cargar el objeto JSON
    mi_archivo = demjson.decode(cadena_json, strict=True)
    
    # modificar las claves según sea necesario
    for j in mi_archivo:
        j["clave1"][0]["clave_2"] = j["clave1"][0].pop("clave_2")
    

    En este código, primero leemos el archivo JSON como una cadena utilizando boto3, y luego utilizamos demjson.decode() para cargar el objeto JSON como una lista de diccionarios. Luego, iteramos sobre cada diccionario y modificamos la clave “clave_2” a “clave2” según sea necesario.

    Ten en cuenta que la opción strict=True en demjson.decode() se utiliza para asegurarse de que el objeto JSON se cargue estrictamente de acuerdo con el estándar JSON. Si estás seguro de que los archivos JSON que estás cargando están bien formados, puedes omitir esta opción.

Comments are closed.