Saltar a contenido

Errores: qué significan y qué hacer

Cómo se leen los errores de tai-sql

Un problema que tú puedes arreglar nunca sale como traceback. Sale así:

❌ La variable de entorno MAIN_DATABASE_URL no está definida
   💡 Defínela en tu entorno o en el fichero .env: MAIN_DATABASE_URL=postgresql://usuario:clave@host:5432/basededatos
   📍 Schema 'public'
   🔗 E011

Cuatro partes: qué ha pasado, qué hacer —siempre está: si falta, es un bug de tai-sql—, dónde, y un código para buscarlo.

Si en vez de eso ves ❌ Error interno de tai-sql: ..., no es culpa de tu schema: es un fallo del framework. Repite con tai-sql --debug <comando> para la traza y repórtalo.

Rango Familia
E001–E010 Definición del schema: tipos, campos, relaciones, constraints, vistas
E011–E015 Entorno y proyecto: variables, proyecto no encontrado, schema no encontrado
E020–E023 Base de datos: conexión, base inexistente, operación fallida, operación insegura
E030 Generación de recursos

Los que más se repiten

La variable de entorno X no está definida (E011)

El datasource(provider=env('X')) se resuelve al importar el schema, así que este error aparece en cualquier comando, no solo en los que se conectan.

Comprueba que la variable está exportada, y que el proceso la ve: tai-sql no carga .env por su cuenta salvo que el proyecto lo haga.

No estás dentro de un proyecto tai-sql (E012)

No hay ningún .taisqlproject por encima del directorio actual. O estás en el sitio equivocado, o el proyecto no se creó con tai-sql init.

El schema 'X' no existe en este proyecto (E013)

El nombre que va en --schema es el del fichero schemas/<nombre>.py, no el nombre del schema en la base de datos. Pueden ser distintos: el segundo es el de datasource(schema=...).

El fichero del schema 'X' tiene un error de sintaxis (E014)

Python no puede importar el fichero. Casi siempre es una de dos: falta from __future__ import annotations, o hay una referencia a una clase declarada más abajo sin él.

La tabla 'X' no declara __tablename__ (E002)

Toda Table y toda View lo necesitan: es el nombre físico en la base de datos.

La tabla 'X' no tiene clave primaria (E002)

Marca al menos una columna con column(primary_key=True). Sin ella no se puede generar el DAO ni comparar el estado con la base de datos.

relation() se ha declarado sin 'backref' (E003)

fields, references y backref son obligatorios. El backref es el nombre que tendrá la relación en el otro extremo.

La relación 'X.y' apunta a 'Z', que no está declarado en este schema (E003)

La tabla destino no está en este schema. Las relaciones entre schemas distintos no se declaran: son dos bases de datos lógicas separadas.

La columna calculada 'X' no declara tipo de retorno (E001)

Una calculada necesita anotación de retorno: -> col[str] en v2, o @calculated_column con -> str en v1.

Hay operaciones que no se pueden ejecutar sobre los datos actuales (E023)

Es el BLOCKED del push. Lo que hay arriba en la salida dice cuál: NULLs en una columna que pasa a obligatoria, duplicados en una que pasa a única, huérfanos en una FK nueva. Se arreglan con los datos, no con el schema:

UPDATE tabla SET columna = 'valor' WHERE columna IS NULL;
La base de datos 'X' no existe en el servidor (E021)

El servidor responde pero la base de datos no está. tai-sql push la crea; tai-sql ping -d te dice si existe sin tocar nada.

Los que no dan error, que son los caros

Estos no revientan. Se manifiestan como «no funciona» horas después.

El cliente generado no refleja el schema

En orden de probabilidad:

  1. No has regenerado. tai-sql generate, o tai-sql push —que regenera al terminar, pero solo si hubo cambios en la base de datos: si tocaste algo que no produce DDL, no regenera nada.
  2. Estás importando otra copia. Si hay una copia vieja en site-packages o en otra ruta del sys.path, gana esa.
  3. Editaste el código generado. Se pisó.
  4. El método que esperabas como columna no lo es. Un método con -> str desnudo y sin @calculated_column es solo un método: no genera columna, y no avisa.

Qué hacer: borrar el directorio generado entero y tai-sql generate. Si después de eso sigue faltando, el problema está en el schema.

push dice que no hay cambios y tú ves que sí

  • Convertir una columna en autoincremental. No se puede aplicar —exige crear una secuencia o una identidad—, así que tampoco se reporta. Hazlo a mano.
  • Un índice creado a mano que el schema no declara: no se elimina nunca, a propósito.
  • Estás mirando otra base de datos. Con env(), la URL sale del entorno del proceso: comprueba con tai-sql info a qué apunta de verdad.

Las relaciones se declararon en los dos lados

Si relation() está en las dos tablas, tai-sql crea dos claves foráneas donde debería haber una. Se declara solo en la tabla que tiene las columnas FK.

feed falla con una columna vectorial que declara encoder

El encoder real vive en el cliente generado, no en tai-sql. Aporta el vector ya calculado en el feed(), o puebla esa columna desde el cliente.

Conexión y permisos

tai-sql ping -s <schema>       # ¿responde el servidor?
tai-sql ping -s <schema> -d    # ¿existe además la base de datos?
tai-sql info                   # ¿a qué está apuntando de verdad?
Síntoma Qué mirar
ModuleNotFoundError de un driver al conectar Falta el extra del motor: pip install 'tai-sql[mysql]', [sqlserver], [bigquery]. PostgreSQL no necesita ninguno
Timeout al conectar Host y puerto de la URL; firewall; si el servidor está en Docker, el nombre de red
password authentication failed La URL. Si la contraseña lleva caracteres especiales, tienen que ir escapados
permission denied for schema El usuario necesita CREATE en el schema para el push, no solo SELECT/INSERT
permission denied to create database push intenta crear la base de datos si no existe. O se la creas tú, o le das el permiso
La extensión vector no se puede crear Instala pgvector en el servidor; CREATE EXTENSION necesita superusuario

Cómo diagnosticar cualquier cosa, en orden

  1. tai-sql info — ¿carga el schema? ¿qué tablas ve? ¿a qué base apunta?
  2. tai-sql ping -d — ¿llega?
  3. tai-sql push --dry-run --verbose — ¿qué DDL saldría?
  4. tai-sql generate — ¿el cliente se regenera sin fallos?
  5. tai-sql --debug <comando> — si algo sale como error interno, la traza.

Los pasos 1 a 3 no modifican nada: se pueden ejecutar siempre.