Saltar a contenido

Vistas y enumerados

Vistas

class ResumenAutor(View):
    """Posts por autor."""
    __tablename__ = 'resumen_autor'
    __query__ = query('resumen_autor.sql')    # se lee de views/<schema>/

    autor_id: col[int]
    nombre: col[str]
    total: col[int]

Y en views/public/resumen_autor.sql:

SELECT
    autor.id   AS autor_id,
    autor.nombre,
    COUNT(post.id) AS total
FROM autor
LEFT JOIN post ON autor.id = post.autor_id
GROUP BY autor.id, autor.nombre

Las columnas hay que declararlas

tai-sql no parsea el SQL. Lo que declares en la clase es lo que tendrán el cliente generado y el diagrama; si no coincide con lo que devuelve la consulta, el fallo aparece al consultar.

Vistas materializadas

class ResumenAutor(View):
    __tablename__ = 'resumen_autor'
    __query__ = query('resumen_autor.sql')
    materialized = True

No todos los motores las tienen. push las crea, las compara y las puede eliminar.

Dependencias

Para que una vista se cree después de lo que consulta, sus dependencias se declaran a mano —el SQL tampoco se parsea para esto:

class ResumenAutor(View):
    __tablename__ = 'resumen_autor'
    __query__ = query('resumen_autor.sql')
    dependencies = [Autor, Post]

Cómo se comparan

push compara el SQL declarado contra la reescritura del motor —lo que devuelve el catálogo al preguntarle por la definición de la vista—, no contra el texto literal. Así, un cambio de formato no produce drift y un cambio real sí.

En el cliente generado

Las vistas son de solo lectura: find_many, count, exists, as_dataframe y las agregaciones. Ni create, ni update, ni delete — ni find, que necesitaría una clave primaria.

stats = public_sync_api.resumen_autor.find_many(limit=10)
df = public_sync_api.resumen_autor.as_dataframe()

Enumerados

class Estado(Enum):
    """Estado de publicación."""
    BORRADOR = 'borrador'
    PUBLICADO = 'publicado'
    ARCHIVADO = 'archivado'


class Post(Table):
    __tablename__ = 'post'

    estado: col[Estado] = column(default=Estado.BORRADOR)
  • Todos los miembros tienen que compartir tipo de valor.
  • Conviene declarar el enumerado antes de las tablas que lo usan: un column(default=Estado.BORRADOR) necesita que la clase ya exista.
  • Cada enumerado se crea como tipo en la base de datos, en los motores que los tienen.

En el cliente generado, cada enumerado es una propiedad de la fachada, con el nombre de la clase en snake_case:

public_sync_api.estado.find_many()   # ['borrador', 'publicado', 'archivado']

Añadir un valor a un enumerado

Es un cambio de schema como cualquier otro: añádelo a la clase y haz push. Quitar un valor que está en uso, en cambio, es lo que hará fallar la transacción.