Saltar a contenido

Motores soportados

Motor provider Extra de tai-sql Extras del proyecto
PostgreSQL postgresql://user:pass@host:5432/db — (psycopg2 va de serie) postgresql, postgresql-async
MySQL mysql+pymysql://user:pass@host:3306/db mysql mysql, mysql-async
SQL Server mssql+pyodbc://user:pass@host:1433/db sqlserver sqlserver, sqlserver-async
BigQuery bigquery://proyecto/dataset bigquery bigquery (solo síncrono)

Todo el SQL dialectal vive en los drivers: tipos, DDL, quoting, upsert y consultas de catálogo. Ni el ORM, ni los generadores, ni la sincronización ramifican por nombre de motor, y por eso un motor nuevo es implementar un contrato, no tocar el núcleo.

Capacidades

Cada driver declara qué objetos de catálogo sabe tener. Lo que el motor no tiene, no se compara: un column(unique=True) en un motor sin restricciones de unicidad no produce drift, porque no es una diferencia por resolver sino una garantía que esa base de datos no ofrece.

PostgreSQL MySQL SQL Server BigQuery
Claves primarias ✅ ✅ ✅ ⚠️ NOT ENFORCED
Claves foráneas ✅ ✅ ✅ ❌
Restricciones de unicidad ✅ ✅ ✅ ❌
Índices ✅ ✅ ✅ ❌
Vistas materializadas ✅ ❌ ❌1 ❌2
Columnas vectoriales ✅ pgvector ❌ ❌ ❌
Cliente asíncrono ✅ ✅ ✅ ❌

Diferencias que conviene conocer

PostgreSQL

Es el motor de referencia: el único con columnas vectoriales (pgvector) y contra el que corre la suite de tests completa. Si tienes elección, es lo que menos sorpresas te va a dar.

MySQL

  • El ALTER COLUMN no puede ser proporcional al diff. MySQL no tiene un ALTER COLUMN por atributo: su MODIFY COLUMN reemplaza la definición entera. La sentencia es idempotente y el push converge, pero un cambio de nullability reescribe la columna. La excepción es el default solo, que sí tiene sentencia propia.
  • Una columna str se compila como VARCHAR(255): MySQL exige una longitud, y 255 es lo máximo que cabe cómodamente en el índice que respalda una restricción de unicidad. Para más, text.

SQL Server

Necesita el ODBC Driver del sistema además de pyodbc; instalar el paquete de Python no basta.

BigQuery

No es una base de datos relacional al uso, y el driver lo refleja:

  • No tiene restricciones de unicidad ni índices de propósito general.
  • Sus claves primarias y foráneas son NOT ENFORCED: metadatos para el optimizador, no garantías. Las foráneas, además, no las devuelve la reflexión, así que no se comparan —una categoría de drift que se pudiera crear y no leer haría que el push no convergiera nunca.
  • No hay autoincremental: no existen las secuencias.
  • Su ALTER COLUMN solo sabe ensanchar un tipo, soltar un NOT NULL y cambiar un default. Volver obligatoria una columna no existe en el motor.
  • De las vistas materializadas el catálogo no da la definición, y las dependencias entre vistas no se publican.
  • El cliente generado en modo async no sirve para BigQuery: no existe dialecto asíncrono. Genera con PythonClientGenerator(mode='sync').

Conectarse necesita el extra bigquery; escribir el DDL y generar el cliente, no.

Cobertura de tests

La suite ejecuta SQL real contra PostgreSQL y MySQL. Para SQL Server y BigQuery lo que hay es un golden de DDL que congela el texto de las sentencias: suficiente para detectar una regresión en el SQL generado, pero no equivalente a ejecutarlo.


  1. SQL Server no tiene vistas materializadas como objeto propio: su equivalente es una vista con un índice agrupado, que se declara y se elimina como una vista normal. ↩

  2. BigQuery sí tiene CREATE MATERIALIZED VIEW, pero su catálogo no devuelve la definición, así que no hay con qué comparar la declarada: cada push la vería como nueva. Declarar una vista materializada contra BigQuery corta con un error que dice qué hacer. ↩