Saltar al contenido principal

Generación de esquemas

[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 →

Introducción

Para facilitar la creación de herramientas que generen ent.Schema de forma programática, ent permite manipular el directorio schema/ mediante el paquete entgo.io/contrib/schemast.

API

Carga

Para manipular un directorio de esquemas existente, primero debemos cargarlo en un objeto schemast.Context:

package main

import (
"fmt"
"log"

"entgo.io/contrib/schemast"
)

func main() {
ctx, err := schemast.Load("./ent/schema")
if err != nil {
log.Fatalf("failed: %v", err)
}
if ctx.HasType("user") {
fmt.Println("schema directory contains a schema named User!")
}
}

Impresión

Para volcar el contenido del contexto en un directorio destino, usa schemast.Print:

package main

import (
"log"

"entgo.io/contrib/schemast"
)

func main() {
ctx, err := schemast.Load("./ent/schema")
if err != nil {
log.Fatalf("failed: %v", err)
}
// A no-op since we did not manipulate the Context at all.
if err := schemast.Print("./ent/schema"); err != nil {
log.Fatalf("failed: %v", err)
}
}

Mutadores

Para modificar el directorio ent/schema, podemos usar schemast.Mutate, que acepta una lista de schemast.Mutator para aplicar al contexto:

package schemast

// Mutator changes a Context.
type Mutator interface {
Mutate(ctx *Context) error
}

Actualmente, solo se implementa un tipo de schemast.Mutator: UpsertSchema:

package schemast

// UpsertSchema implements Mutator. UpsertSchema will add to the Context the type named
// Name if not present and rewrite the type's Fields, Edges, Indexes and Annotations methods.
type UpsertSchema struct {
Name string
Fields []ent.Field
Edges []ent.Edge
Indexes []ent.Index
Annotations []schema.Annotation
}

Para usarlo:

package main

import (
"log"

"entgo.io/contrib/schemast"
"entgo.io/ent"
"entgo.io/ent/schema/field"
)

func main() {
ctx, err := schemast.Load("./ent/schema")
if err != nil {
log.Fatalf("failed: %v", err)
}
mutations := []schemast.Mutator{
&schemast.UpsertSchema{
Name: "User",
Fields: []ent.Field{
field.String("name"),
},
},
&schemast.UpsertSchema{
Name: "Team",
Fields: []ent.Field{
field.String("name"),
},
},
}
err = schemast.Mutate(ctx, mutations...)
if err := ctx.Print("./ent/schema"); err != nil {
log.Fatalf("failed: %v", err)
}
}

Tras ejecutar este programa, observa que existen dos nuevos archivos en el directorio de esquemas: user.go y team.go:

// user.go
package schema

import (
"entgo.io/ent"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
)

type User struct {
ent.Schema
}

func (User) Fields() []ent.Field {
return []ent.Field{field.String("name")}
}
func (User) Edges() []ent.Edge {
return nil
}
func (User) Annotations() []schema.Annotation {
return nil
}
package schema

import (
"entgo.io/ent"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
)

type Team struct {
ent.Schema
}

func (Team) Fields() []ent.Field {
return []ent.Field{field.String("name")}
}
func (Team) Edges() []ent.Edge {
return nil
}
func (Team) Annotations() []schema.Annotation {
return nil
}

Trabajando con aristas

Las aristas se definen en ent de esta manera:

edge.To("edge_name", OtherSchema.Type)

Esta sintaxis depende de que la estructura OtherSchema ya exista cuando definimos la arista para poder referenciar su método Type. Al generar esquemas programáticamente, necesitamos describir la arista al generador de código antes de que existan las definiciones de tipos. Para ello puedes hacer algo como:

type placeholder struct {
ent.Schema
}

func withType(e ent.Edge, typeName string) ent.Edge {
e.Descriptor().Type = typeName
return e
}

func newEdgeTo(edgeName, otherType string) ent.Edge {
// we pass a placeholder type to the edge constructor:
e := edge.To(edgeName, placeholder.Type)
// then we override the other type's name directly on the edge descriptor:
return withType(e, otherType)
}

Ejemplos

El plugin protoc-gen-ent (doc) para protoc genera ent.Schema a partir de archivos .proto usando schemast para manipular el directorio schema destino. Para ver cómo funciona, consulta el código fuente.

Advertencias

schemast sigue siendo experimental y sus APIs podrían cambiar en el futuro. Además, actualmente no se soporta una pequeña parte de la API de definición de ent.Field. Para ver la lista completa de características no soportadas, consulta el código fuente.