Saltar al contenido principal

Anunciando v0.10: Ent obtiene un nuevo motor de migraciones

· 6 min de lectura
[Traducción Beta No Oficial]

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Querida comunidad,

Me complace anunciar el lanzamiento de la próxima versión de Ent: v0.10. Han pasado casi seis meses desde v0.9.1, así que naturalmente esta versión incluye un montón de novedades. Aún así, quería dedicar tiempo para hablar sobre una mejora importante en la que hemos estado trabajando durante los últimos meses: un nuevo motor de migraciones.

Presentamos: Atlas

El actual motor de migraciones de Ent es genial y hace cosas bastante interesantes que nuestra comunidad ha estado usando en producción durante años, pero con el tiempo empezaron a acumularse problemas que no podíamos resolver con la arquitectura existente. Además, consideramos que los marcos de migración de bases de datos actuales dejan mucho que desear. Hemos aprendido tanto como industria sobre la gestión segura de cambios en sistemas productivos en la última década con principios como Infraestructura-como-Código y gestión declarativa de configuración, que simplemente no existían cuando se concibieron la mayoría de estos proyectos.

Al ver que estos problemas eran bastante genéricos y relevantes para aplicaciones independientemente del framework o lenguaje de programación en el que estuvieran escritas, vimos la oportunidad de solucionarlos como infraestructura común que cualquier proyecto podría usar. Por esta razón, en lugar de simplemente reescribir el motor de migraciones de Ent, decidimos extraer la solución a un nuevo proyecto de código abierto, Atlas (GitHub).

Atlas se distribuye como una herramienta CLI que utiliza un nuevo DDL basado en HCL (similar a Terraform), pero también puede usarse como un paquete de Go. Al igual que Ent, Atlas tiene licencia Apache 2.0.

Finalmente, tras mucho trabajo y pruebas, la integración de Atlas para Ent está lista para usarse. Esta es una gran noticia para muchos de nuestros usuarios que abrieron issues (como #1652, #1631, #1625, #1546 y #1845) que no podían resolverse adecuadamente con el sistema de migraciones existente, pero que ahora se solucionan con el motor Atlas.

Como con cualquier cambio sustancial, usar Atlas como motor de migraciones en tu proyecto es actualmente opcional. En un futuro próximo, cambiaremos a un modo de exclusión voluntaria (opt-out), y finalmente dejaremos obsoleto el motor actual. Naturalmente, esta transición se hará gradualmente, y avanzaremos según recibamos indicaciones positivas de la comunidad.

Cómo empezar con las migraciones Atlas para Ent

Primero, actualiza a la última versión de Ent:

go get entgo.io/ent@v0.10.0

Luego, para ejecutar una migración con el motor Atlas, usa la opción WithAtlas(true).

package main
import (
"context"
"log"
"<project>/ent"
"<project>/ent/migrate"
"entgo.io/ent/dialect/sql/schema"
)
func main() {
client, err := ent.Open("mysql", "root:pass@tcp(localhost:3306)/test")
if err != nil {
log.Fatalf("failed connecting to mysql: %v", err)
}
defer client.Close()
ctx := context.Background()
// Run migration.
err = client.Schema.Create(ctx, schema.WithAtlas(true))
if err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}

¡Y eso es todo!

Una de las grandes mejoras del motor Atlas sobre el código existente de Ent es su estructura en capas, que separa claramente entre inspección (entender el estado actual de una base de datos), diferenciación (calcular la diferencia entre el estado actual y el deseado), planificación (calcular un plan concreto para solucionar la diferencia) y aplicación. Este diagrama muestra cómo Ent utiliza Atlas:

atlas-migration-process

Además de las opciones estándar (ej. WithDropColumn, WithGlobalUniqueID), la integración de Atlas proporciona opciones adicionales para intervenir en los pasos de migración del esquema.

Aquí tenéis dos ejemplos que muestran cómo conectar con los pasos Diff y Apply de Atlas.

package main
import (
"context"
"log"
"<project>/ent"
"<project>/ent/migrate"
"ariga.io/atlas/sql/migrate"
atlas "ariga.io/atlas/sql/schema"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql/schema"
)
func main() {
client, err := ent.Open("mysql", "root:pass@tcp(localhost:3306)/test")
if err != nil {
log.Fatalf("failed connecting to mysql: %v", err)
}
defer client.Close()
ctx := context.Background()
// Run migration.
err := client.Schema.Create(
ctx,
// Hook into Atlas Diff process.
schema.WithDiffHook(func(next schema.Differ) schema.Differ {
return schema.DiffFunc(func(current, desired *atlas.Schema) ([]atlas.Change, error) {
// Before calculating changes.
changes, err := next.Diff(current, desired)
if err != nil {
return nil, err
}
// After diff, you can filter
// changes or return new ones.
return changes, nil
})
}),
// Hook into Atlas Apply process.
schema.WithApplyHook(func(next schema.Applier) schema.Applier {
return schema.ApplyFunc(func(ctx context.Context, conn dialect.ExecQuerier, plan *migrate.Plan) error {
// Example to hook into the apply process, or implement
// a custom applier. For example, write to a file.
//
// for _, c := range plan.Changes {
// fmt.Printf("%s: %s", c.Comment, c.Cmd)
// if err := conn.Exec(ctx, c.Cmd, c.Args, nil); err != nil {
// return err
// }
// }
//
return next.Apply(ctx, conn, plan)
})
}),
)
if err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}

Qué viene después: v0.11

Sé que hemos tardado en sacar esta versión, pero la próxima está a la vuelta de la esquina. Esto es lo que viene en la v0.11:

  • Soporte para esquemas de relaciones/edges - permitiendo adjuntar campos de metadatos a relaciones.

  • Reimplementación de la integración con GraphQL para ser totalmente compatible con la especificación Relay. Soporte para generar recursos GraphQL (esquemas o servidores completos) a partir de esquemas Ent.

  • Implementación del "Autor de Migraciones": las librerías de Atlas incluyen infraestructura para crear directorios de migraciones "versionadas", como se usa comúnmente en muchos frameworks de migraciones (como Flyway, Liquibase, go-migrate, etc.). Muchos usuarios han creado soluciones para integrarse con este tipo de sistemas, y planeamos usar Atlas para ofrecer una infraestructura sólida para estos flujos.

  • Hooks de consulta (interceptores) - actualmente los hooks solo están soportados para Mutaciones. Muchos usuarios han solicitado añadir soporte también para operaciones de lectura.

  • Relaciones polimórficas - El issue sobre añadir soporte para polimorfismo lleva abierto más de un año. Con la llegada de los Tipos Genéricos en Go 1.18, queremos reabrir el debate sobre una posible implementación usando esta característica.

Para finalizar

Además del emocionante anuncio sobre el nuevo motor de migraciones, esta versión es enorme en tamaño y contenido, con 199 commits de 42 colaboradores únicos. Ent es un esfuerzo comunitario que mejora cada día gracias a todos vosotros. Así que un enorme gracias y reconocimiento infinito a todos los que habéis participado en esta release (ordenados alfabéticamente):

attackordie, bbkane, bodokaiser, cjraa, dakimura, dependabot, EndlessIdea, ernado, evanlurvey, freb, genevieve, giautm, grevych, hedwigz, heliumbrain, hilakashai, HurSungYun, idc77, isoppp, JeremyV2014, Laconty, lenuse, masseelch, mattn, mookjp, msal4, naormatania, odeke-em, peanut-cc, posener, RiskyFeryansyahP, rotemtam, s-takehana, sadmansakib, sashamelentyev, seiichi1101, sivchari, storyicon, tarrencev, ThinkontrolSY, timoha, vecpeng, yonidavidson y zeevmoney.

Un saludo, Ariel

[Para más noticias y actualizaciones de Ent:]