TypeError: string indices must be integers - Guardando datos de un JSON a la base de datos

Pregunta de la clase:
Bernardo Augusto García Loaiza

Bernardo Augusto García Loaiza

Pregunta
student
hace 9 años

Tengo la siguiente situación:

El modelo

RehabilitationSession
además de otros datos estos campos de interés:

<code> class RehabilitationSession(models.Model): ... minimum = models.DecimalField( max_digits=5,decimal_places=2,verbose_name='Valor mínimo' ) maximum = models.DecimalField( max_digits=5, decimal_places=2,verbose_name='Valor máximo' ) median = models.DecimalField( max_digits=5,decimal_places=2,verbose_name='Valor medio' ) mode = models.DecimalField( max_digits=5, decimal_places=2,verbose_name='Valor moda' ) ...

En este modelo, su información se completa con un archivo JSON que provee información de una aplicación externa y precisamente ese JSON me brinda los valores para estos campos de

minimum
,
median
,
mode
y
maximum

Entonces es en el comportamiento de la vista de Detalle de un objeto

RehabilitationSession
en donde deseo tomar esa información del documento JSON y guardarlo a la base de datos.

El documento JSON es este. Lo doy a conocer en la totalidad de su estructura con el objetivo de poder dimensionar el error que tengo en caso tal:

<code> { "paciente": { "id": 1234, "nombre": "Pablo Andrés Agudelo Marenco", "sesion": { "id": 3, "juego": [ { "nombre": "bonzo", "nivel": [ { "id": 1234, "nombre": "caida libre", "segmento": [ { "id": 12345, "nombre": "Hombro", "movimiento": [ { "id": 1234, "nombre": "Flexion", "metricas": [ { "min": 12, "max": 34, "media": 23, "moda": 20 } ] } ] } ], "___léeme___": "El array 'iteraciones' contiene las vitorias o derrotas con el tiempo en segundos de cada iteración", "iteraciones": [ { "victoria": true, "tiempo": 120 }, { "victoria": false, "tiempo": 232 } ] } ] } ] } } }

En mi vista basada en clase del detalle de un objeto

RehabilitationSession
es en donde leo el documento JSON y comparo los identificadores tanto del objeto en la base de datos como el del
JSON
(
["paciente"]["sesion"]["id"]
) y si coinciden procedo con el guardado de datos.

Tengo lo siguiente:

<code> class RehabilitationSessionDetail(LoginRequiredMixin,DetailView): model = RehabilitationSession template_name = 'rehabilitationsession_detail.html' context_object_name = 'sessiondetail' def get_context_data(self, **kwargs): context=super(RehabilitationSessionDetail, self).get_context_data(**kwargs) user = self.request.user with open('ProcessedMetricsFinal.json') as data_file: session_data=json.loads(data_file.read()) context['session_data'] = session_data #Capturar el ID de la sesión del JSON session_id_json = session_data["paciente"]["sesion"]["id"] #Capturar el ID de la sesión de la base de datos session_id_db=int(self.kwargs.get('pk')) #Comparar esos dos ID, si son iguales: if session_id_db==session_id_json: # Guardando datos a la base de datos for record in session_data: RehabilitationSession.objects.filter(id=session_id_db).update( minimum=record['min'], maximum=record['max'], median=record['media'], mode=record['moda']) else: context=super(RehabilitationSessionDetail, self).get_context_data(**kwargs) return context

Entonces cuando voy a mi url de detalle, que es la que llama a esta vista, cuando se cumple la condición de comparar los id’s tanto del documento JSON y el objeto en la base de datos, obtengo el siguiente error:

<code> File "/home/bgarcial/workspace/neurorehabilitation_project/medical_encounter_information/views.py", line 187, in get_context_data minimum=record['min'], TypeError: string indices must be integers [17/Nov/2016 02:07:17] "GET /sesiones-de-rehabilitacion/3 HTTP/1.1" 500 122694

No se si tal vez como estoy indagando en mi vista por las claves

min
,
max
,
media
,
moda
las cuales están en un nivel de identación mayor … ¿deba recorrerlo con varios índices en mi ciclo
for
?

1 respuestas
para escribir tu comentario
    Bernardo Augusto García Loaiza

    Bernardo Augusto García Loaiza

    student
    hace 9 años

    El error señala que estoy iterando con un string que es mi índice, y éstos no pueden ser strings sino enteros

    Para iterar sobre un diccionario no podría hacerlo como una lista normal (sabiendo que los JSON son diccionarios para python), de modo que al recorrerlos como lo estas haciendo en esta linea:

    for record in session_data: # estas accediendo a cada llave de el JSON principal

    lo correcto seria iterar sobre el diccionario asi:

    for key, value in session_data.items():

    Aunque si sabemos que lo que tenemos en la variable

    record
    son strings, se podría iterar asi:

    <code> for key in session_data: record = session_data[key]['sesion']['juego'][0]['nivel'][0]['segmento'][0]['movimiento'][0]['metricas'][0] RehabilitationSession.objects.filter(id=session_id_db).update( minimum=record['min'], maximum=record['max'], median=record['media'], mode=record['moda'] )
Curso de Python y Django 2016

Curso de Python y Django 2016

Aprende Python desde cero y crea tu primera aplicación web completa en Django. Entiende las bases del lenguaje, sus funciones, conoce cómo conectarte a bases de datos y termina creando una API REST de manera profesional para tu app.

Curso de Python y Django 2016
Curso de Python y Django 2016

Curso de Python y Django 2016

Aprende Python desde cero y crea tu primera aplicación web completa en Django. Entiende las bases del lenguaje, sus funciones, conoce cómo conectarte a bases de datos y termina creando una API REST de manera profesional para tu app.