tai-sql
Framework declarativo de Python, sobre SQLAlchemy, que gestiona el ciclo de vida completo de una base de datos. Declaras el modelo una vez, en un fichero Python, y a partir de ahí tai-sql sincroniza la estructura de la base de datos, genera un cliente Python completo —modelos, DTOs y DAOs síncronos y asíncronos— y dibuja el diagrama entidad-relación.
schemas/public.py ──▶ tai-sql push ──▶ la base de datos se parece al schema
──▶ tai-sql generate ──▶ cliente Python + diagrama ER
──▶ tai-sql feed ──▶ datos iniciales
◀── tai-sql pull ◀── una base de datos que ya existe
Motores soportados: PostgreSQL, MySQL, SQL Server y BigQuery.
📖 El manual completo está en triplealpha-innovation.github.io/tai-sql
Quickstart
pip install tai-sql # PostgreSQL funciona sin extras
tai-sql init -n mi_proyecto -s public # crea el proyecto
cd mi_proyecto
export MAIN_DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
tai-sql install # instala lo que el cliente generado necesitará
Edita schemas/public.py:
# -*- coding: utf-8 -*-
from __future__ import annotations
from tai_sql import *
from tai_sql.generators import *
datasource(provider=env('MAIN_DATABASE_URL'), schema='public', syntax='v2')
generate(
PythonClientGenerator(output_dir='database'),
ERDiagramGenerator(output_dir='diagrams', format='html'),
)
class Usuario(Table):
"""Usuarios del sistema."""
__tablename__ = 'usuario'
id: col[int] = column(primary_key=True, autoincrement=True)
nombre: col[str]
email: col[str] = column(unique=True)
creado_en: col[datetime] = column(server_now=True)
posts: onetomany[Post]
class Post(Table):
"""Posts publicados."""
__tablename__ = 'post'
id: col[bigint] = column(primary_key=True, autoincrement=True)
titulo: col[str]
contenido: col[text]
autor_id: col[int]
autor: manytoone[Usuario] = relation(fields=['autor_id'], references=['id'], backref='posts')
tai-sql push --dry-run --verbose # enseña el DDL sin ejecutar nada
tai-sql push # lo aplica y regenera el cliente
Y a usarlo:
from database.public import public_sync_api, UsuarioCreate
usuario = public_sync_api.usuario.create(UsuarioCreate(nombre='Ana', email='ana@example.com'))
usuarios = public_sync_api.usuario.find_many(limit=10, includes=['posts'])
Los cinco principios que explican el resto
- El schema es la única fuente de verdad. Todo lo demás —DDL, cliente, diagramas— es derivado y desechable. Si el cliente generado no hace lo que necesitas, no se edita el cliente: se arregla el schema y se regenera.
- Mapear y después actuar. Todo comando importa el schema, lo analiza y actúa sobre ese mapeo. Ningún comando parsea el fichero por su cuenta.
- El código generado nunca importa
tai_sql. tai-sql es una herramienta de desarrollo, no una dependencia de producción: el cliente se despliega donde tai-sql no está instalado. - Modelo declarativo, sin migraciones versionadas. No hay ficheros de migración:
pushcompara el estado declarado con el real y genera el DDL que hace falta. - Definición ≠ runtime. El ORM de tai-sql describe; el comportamiento en producción vive en el código generado.
Qué trae
| Schema declarativo | Tablas, relaciones, vistas, enumerados, constraints e índices de varias columnas, columnas calculadas y jerarquías. Dos sintaxis, v1 y v2, y las dos se soportan |
| Sincronización sin migraciones | push compara y genera el DDL, clasificando cada operación en SAFE / WARNING / BLOCKED antes de tocar nada |
| Cliente Python generado | CRUD completo, filtros por tipo de columna, relaciones anidadas, agregaciones con GROUP BY, DataFrames, RLS, auditoría y transacciones, en síncrono y asíncrono |
| Triggers transpilados | Lógica de negocio declarada en el schema que se inlinea en los DAOs: sin coste en runtime |
| Cifrado y vectores | Columnas cifradas con Fernet, transparentes al leer, y columnas vectoriales con pgvector y búsqueda por similitud |
| Diagrama ER | Una página HTML interactiva, o una imagen con Graphviz |
| Introspección | pull escribe el schema de una base de datos que ya existe |
| Reglas para asistentes de IA | rules install deja en tu proyecto la documentación que un asistente necesita, incluida la derivada de tu schema |
El manual
| Sección | Qué responde |
|---|---|
| Instalación | Qué instalar, y por qué son dos instalaciones y no una |
| Tu primer proyecto | De cero a un cliente generado funcionando |
| El schema | Todo lo que se puede declarar, y cómo |
| El CLI | Qué hace cada comando, y qué puede destruir push |
| El cliente generado | La API que vas a usar desde tu aplicación |
| Referencia | Firmas del DSL, motores, extensión y catálogo de errores |
Desarrollo
git clone https://github.com/triplealpha-innovation/tai-sql
cd tai-sql
poetry install --all-extras # los extras no son opcionales para la suite
poetry run pytest # todo lo que el entorno permita
poetry run pytest -m "not db and not mysql" # lo que corre sin ninguna base de datos
poetry run pytest -m mysql # el ciclo completo contra MySQL
Los tests marcados db necesitan un PostgreSQL alcanzable y se saltan si no lo hay; los
marcados mysql, un MySQL en TAI_SQL_MYSQL_URL. Sus schemas salen de tests/fixtures/project/.
El CI tiene tres workflows: tests.yaml ejecuta la suite en cada push y PR a main y dev —un
trabajo con PostgreSQL y otro con MySQL—, docs.yaml publica el manual y publish.yaml publica
a PyPI en push a main. La rama de trabajo habitual es dev, y la versión se bumpea a mano en
pyproject.toml.
El manual, en local
pip install -r docs/requirements.txt
mkdocs serve # http://127.0.0.1:8000, con recarga en caliente
mkdocs build --strict # lo mismo que valida el CI
El manual vive en docs/ y es para quien usa tai-sql. Las reglas de diseño internas
(.claude/rules/) y el README.md de cada paquete son para quien trabaja en tai-sql, y no
se publican: son dos audiencias con preguntas distintas.
El mapa del código
| Ruta | Qué es |
|---|---|
tai_sql/orm/ |
El mapeo, en cuatro capas: declarative/ → analysis/ → model/ → mapping/ |
tai_sql/sync/ |
Sincronización schema ↔ BD: state/ → diff/ → report.py → plan/ → safety.py → executor.py |
tai_sql/feed/ |
Poblar la base de datos: recoger → planificar → aplicar en una transacción |
tai_sql/introspect/ |
La dirección contraria: BD existente → fichero de schema |
tai_sql/drivers/ |
Todo el SQL dialectal, más las capacidades de cada motor |
tai_sql/generators/ |
Cliente Python, diagrama ER y reglas |
tai_sql/connection/ |
Con qué se conecta tai-sql y cómo se conectará el cliente generado |
tai_sql/cli/ |
El CLI de Click |
tai_sql/errors/ |
TaiSqlError (mensaje + solución obligatoria) y su presentador |
Cada uno de esos paquetes tiene su propio README.md con el detalle.
Licencia
MIT. Ver LICENSE.
Desarrollado por Triple Alpha Innovation · Issues
Release files for tai-sql 0.7.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tai_sql-0.7.9.tar.gz | 602.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tai_sql-0.7.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / tai_sql-0.7.9.tar.gz
| Download URL | tai_sql-0.7.9.tar.gz |
|---|---|
| Size | 602.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aab96fba81a8a4244432f61384adbbc5253568f15f20a62158a895d131ce6f55
|
|
BLAKE2b-256 checksum How to use checksums |
874f715cd2a6eade0de84e817a721e5d8c82394ffb49dfefa6d802017fdcb321
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.5.1 CPython/3.11.0 Linux/6.17.0-1022-azure
|
Release files / tai_sql-0.7.9-py3-none-any.whl
| Download URL | tai_sql-0.7.9-py3-none-any.whl |
|---|---|
| Size | 739.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e4f15419099cac5e19985a5d2e0c7e011f617b6f2cad4537ab4a12f66a8daab3
|
|
BLAKE2b-256 checksum How to use checksums |
bb961102346da844076c860a06e7b62126cc8126e8fce0d3e80c1c2bba7e0e2e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.5.1 CPython/3.11.0 Linux/6.17.0-1022-azure
|