Saltar a contenido

feed() — datos iniciales

Un método de instancia que devuelve una lista de modelos, con relaciones anidadas si hace falta. Lo ejecuta tai-sql feed en orden topológico por claves foráneas.

class Rol(Table):
    __tablename__ = 'rol'
    __constraints__ = unique_constraint('nombre', 'tenant_id')   # clave natural

    id: col[int] = column(primary_key=True, autoincrement=True)
    nombre: col[str]
    tenant_id: col[int]

    def feed(self) -> List[Rol]:
        """Datos iniciales. Se ejecutan con: tai-sql feed"""
        return [
            Rol(nombre='admin', tenant_id=1),
            Rol(nombre='lector', tenant_id=1),
        ]

Con relaciones anidadas

Un feed() puede construir el árbol entero, y tai-sql resuelve las claves foráneas:

class Usuario(Table):
    __tablename__ = 'usuario'

    def feed(self) -> List[Usuario]:
        return [
            Usuario(
                nombre='Ana',
                email='ana@example.com',
                posts=[
                    Post(titulo='Primero', contenido='Hola', comentarios=[
                        Comment(contenido='¡Bien!'),
                    ]),
                    Post(titulo='Segundo', contenido='Otro día'),
                ],
            ),
        ]

La clave natural no es opcional

El feed hace upsert sobre la clave natural de la tabla, que es una unique_constraint.

Una tabla sin clave natural corta el feed

Si la tabla no declara ninguna y su clave primaria es autoincremental, no hay clave de conflicto: cada ejecución insertaría las mismas filas otra vez. El plan lo detecta antes de ejecutar y corta con un error que explica cómo darle identidad. --force lo salta, con las consecuencias que eso tiene.

Dos columnas unique=True independientes son dos identidades, no una compuesta: si la clave natural es la combinación, decláralo con unique_constraint('a', 'b').

Qué tener en cuenta

  • El feed() no necesita rellenar todas las columnas. Una columna que no rellene vale None —que es lo que tendrá en la base de datos— y las calculadas lo ven así.
  • No codifica vectores: una columna vectorial con encoder y sin valor es un error. Ver columnas vectoriales.
  • Las columnas cifradas sí se cifran al insertarlas.
  • Un feed() es un método normal: no lleva col[...] ni decorador, así que el análisis no lo confunde con una columna calculada.

Cuándo se ejecuta

tai-sql feed              # cuando tú quieras
tai-sql push --with-feed  # entre la creación de las tablas y la aplicación de las FKs

La segunda forma sirve cuando los datos iniciales son necesarios para que las claves foráneas se puedan aplicar sin filas huérfanas.