domingo, 1 de marzo de 2026

DATOS. Acceso a datos

CSV. Datos estructurados (II)

Módulo CSV. Nuevo registro de datos

En la entrada precedente aprendimos a acceder a un archivo .csv usando el módulo CSV; en la actual aprenderemos a añadir registros usando el mismo módulo. Además iremos directos al grano, digo, al script...



import csv
import os
from datetime import datetime

ruta_archivo = 'datos\libros3.csv'
NOMBRE_CAMPO_FECHA = 'fecha_lectura'

def sesion_carga_masiva():
    if not os.path.exists(ruta_archivo):
        print(f"❌ El archivo '{ruta_archivo}' no existe.")
        return

    try:
        # 1. Carga inicial para conocer la estructura y el último ID
        with open(ruta_archivo, mode='r', encoding='utf-8', newline='') as archivo:
            lector = csv.reader(archivo)
            cabecera = next(lector)
            datos_existentes = list(lector)
            
        # El ID inicial se basa en lo que ya hay en el archivo
        siguiente_id = len(datos_existentes) + 1
        campos_a_pedir = cabecera[1:-2]

        print(f"--- 🚀 Sesión iniciada. Para terminar escribe 'salir'.\n")

        while True:
            print(f"📝 Preparando Registro #{siguiente_id}:")
            datos_usuario = {}
            cancelar = False

            # 2. Bucle para pedir cada campo de la cabecera
            for columna in campos_a_pedir:
                valor = input(f"   {columna}: ").strip()
                
                if valor.lower() == 'salir':
                    cancelar = True
                    break
                datos_usuario[columna] = valor

            if cancelar: 
                break

            # 3. Procesamiento de Fecha y Validación
            fecha_str = datos_usuario.get(NOMBRE_CAMPO_FECHA)
            try:
                fecha_obj = datetime.strptime(fecha_str, "%d/%m/%Y")
                mes_auto = fecha_obj.month
                anio_auto = fecha_obj.year

                # 4. Construcción de la fila
                nueva_fila = [siguiente_id]
                for columna in campos_a_pedir:
                    nueva_fila.append(datos_usuario[columna])
                nueva_fila.extend([anio_auto,mes_auto])

                # 5. Guardado físico en el CSV
                with open(ruta_archivo, mode='a', encoding='utf-8', newline='') as archivo_escritura:
                    escritor = csv.writer(archivo_escritura)
                    escritor.writerow(nueva_fila)

                print(f"✅ Registro #{siguiente_id} guardado con éxito.\n")
                print("Escribe 'salir' para finalizar registro.\n")
                
                # Incrementamos el ID para el próximo libro de esta misma sesión
                siguiente_id += 1

            except ValueError:
                print(f"\n❌ ERROR: '{fecha_str}' no es una fecha válida (DD/MM/AAAA).")
                print("⚠️ Este registro no se guardó. Por favor, reinténtalo.\n")
                # No incrementamos el ID porque el registro falló

        print(f"\n--- Sesión finalizada. Se han añadido nuevos libros. ---")

    except Exception as e:
        print(f"❌ Error crítico en la sesión: {e}")

if __name__ == "__main__":
    sesion_carga_masiva()


Tomo como referencia el mismo conjunto de datos (libros3.csv) que nos sirvió para aprender a acceder y visualizar registros, pero esta vez planteo un procedimiento simple de escritura de registros mediante la función csv.writer(). Además de esta función, writerow() también es básica para el correcto funcionamiento del script, ya que es la que se encarga de añadir un uevo registro a nuestro documento.

En este caso utilizo una función (sesion_carga_masiva()), a la que llamo mediante el procedimiento if __name__ == "__main__":, aun pendiente de explicación. Todo llegará.

Aunque el usuario debe introducir la mayoría de los campos, algunos se implementan automáticamente. Tal es el caso del id del libro (siguiente_id = len(datos_existentes) + 1) y de los datos correspondientes al año y al mes de lectura, dereivados ambos del campo fecha_lectura (nueva_fila.extend([anio_auto,mes_auto])).

Dado que el script debe permitir la entrada múltiple de registros, se implementa un bucle (while True:) que lo hace posible, requiriendo al usuario la expresión 'salir' para cerrar el bucle y finalizar el script.