Saltar a contenido

10 · Anexo: Migración de 1.5 a 2.0

Diagrama de Decisión

flowchart TD
    A["¿Existen bases de datos<br/>DuckDB en producción?"] -->|Sí| B["Backup + inventario<br/>de consumidores"]
    A -->|No| C["Entorno nuevo y a probar"]
    B --> D["Probar apertura en 2.0:<br/>mantiene el formato 1.x"]
    D --> E["¿Necesario volver atrás?"]
    E -->|Sí| F["No crear ficheros nuevos<br/>con formato 2.0"]
    E -->|No| G["Migrar y fijar formato"]
    C --> H["Ejecutar suite de cuadernos<br/>y pipelines"]
    H --> I{"¿Todo verde?"}
    I -->|Sí| J["Adelante 👌👌"]
    I -->|No| K["Corregir API y repetir"]

Resumen de incompatibilidades

Área Cambio Acción
Almacenamiento Nuevo formato v2.0 por defecto. Las versiones < 2.0 no pueden leerlo Copia de seguridad previa; fijar el formato si hay consumidores antiguos
Python Requiere 3.11+ Subir intérprete en CI y en los cuadernos
Polars/Arrow en resultados .pl(), .fetch_arrow_table() fuera de execute() Usar relaciones: con.sql(q).pl()
Lectura incremental fetchone()/fetchmany() eliminados de relaciones Mantener sobre con.execute(q)
Lambda x -> ... desactivado por defecto lambda x: ..., lambda x, i: ...
Extensiones nativas API de C/C++ reelaborada y versionada (ABI) Recompilar extensiones
ICU Fuera del binario principal INSTALL icu; LOAD icu;

Se mantiene/preserva inalterado

  • Consultas SQL corrientes, tipos, read_parquet, read_csv.
  • Ficheros .duckdb antiguos: la 2.0 los abre y conserva su versión de formato al escribir.
  • El modelo in-process: import duckdb sigue funcionando igual.

Compatibilidad de formato

-- Comprobar la versión de almacenamiento de un fichero
SELECT * FROM pragma_database_size();   -- y consulta storage_version si está expuesta

-- Escribir un fichero pensado para lectores antiguos (opción de compatibilidad)
ATTACH 'nuevo.duckdb' AS n (STORAGE_VERSION 'v1.0.0');

Comprueba la sintaxis en el build

Las opciones de compatibilidad de formato se documentan en la guía de migración de la versión que corresponda. Verificar con SELECT * FROM duckdb_settings() WHERE name ILIKE '%storage%' antes de confiar en un literal concreto.

Secuencia recomendada

  1. Inventario: qué procesos abren .duckdb, qué extensiones usan, qué versión de Python.
  2. Copia de las bases y de los Parquet críticos.
  3. Rama con duckdb==2.0.0 y la suite de tests/cuadernos.
  4. Buscar ->, .pl(), fetch_arrow_table, fetchone en el código:
    grep -rn -- "->" --include=*.py --include=*.ipynb . | grep -i lambda
    grep -rn "fetch_arrow_table\|\.pl()" --include=*.py --include=*.ipynb .
    
  5. Probar en desarrollo con tráfico o datos reales una semana.
  6. Desplegar. La 2.0.1 estaba prevista para el 18 de noviembre; la 1.5 sigue soportada hasta marzo de 2027: no hay prisa.

Diferencias de comportamiento que despistan

Situación 1.5 2.0
con.execute(q).df() funciona funciona
con.execute(q).pl() funciona AttributeError
con.sql(q).fetchone() funciona AttributeError
x -> x + 1 funciona Binder Error
_metadata.file_path funcionaba no disponible (usa filename=true)
read_json_auto(..., auto_expand=...) aceptado parámetro inexistente
Tabla creada dentro de CONNECT — efímera, no persiste

Todo lo mostrado ha sido verificado ejecutando duckdb 2.0.0 en el entorno de preparación del taller.