ent for Go: A Complete Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

ent for Go: Complete Guide to ORM with Code Generation

\n\n

In the world of Go development, there are many ORM libraries, but ent from Facebook (now Meta) holds a special place. It's not just another ORM — it's a powerful framework for working with databases, based on code generation. Instead of using reflection or interfaces at runtime, ent generates strictly typed Go code based on your data schema. This means many errors related to types and queries are caught at compile time, not in production.

\n\n

Why do you need ent? If you work with relational databases (PostgreSQL, MySQL, SQLite) and want strict typing, IDE autocompletion, and minimal boilerplate code — ent is your choice. It's ideal for projects where performance and code maintainability matter. Unlike GORM, which uses reflection, ent generates code for each model, making it significantly faster and safer.

\n\n

In this article, we will thoroughly explore ent: from installation to advanced techniques. You will learn how to define a data schema, generate code, perform CRUD operations, build complex queries with relationship graphs, and avoid common mistakes. The material is intended for developers already familiar with Go basics.

\n\n

Installation

\n\n

To get started with ent, you need Go version 1.16 or higher. Installation includes the ent package itself and a command-line utility for code generation.

\n\n
# Install the command-line utility\ngo install entgo.io/ent/cmd/ent@latest\n\n# Initialize the project (creates the ent/ directory)\ngo run entgo.io/ent/cmd/ent init User
\n\n

The first command installs the ent binary into your $GOPATH/bin. The second command creates the project structure: an ent/ directory with a schema file for the User entity. After that, you can start defining fields and relationships.

\n\n

Quick Start: Minimal Working Example

\n\n

Let's create a simple user model and perform basic operations. First, define the schema in the file ent/schema/user.go:

\n\n
package schema\n\nimport (\n    "entgo.io/ent"\n    "entgo.io/ent/schema/field"\n)\n\n// User holds the schema definition for the User entity.\ntype User struct {\n    ent.Schema\n}\n\n// Fields of the User.\nfunc (User) Fields() []ent.Field {\n    return []ent.Field{\n        field.String("name").\n            Unique().\n            NotEmpty(),\n        field.Int("age").\n            Positive(),\n        field.String("email").\n            Unique(),\n    }\n}
\n\n

Now generate the code:

\n\n
go generate ./ent
\n\n

After that, you can use the generated code in main.go:

\n\n
package main\n\nimport (\n    "context"\n    "fmt"\n    "log"\n\n    "your-project/ent"\n    "your-project/ent/user"\n\n    _ "github.com/mattn/go-sqlite3"\n)\n\nfunc main() {\n    // Create a client for SQLite (in-memory)\n    client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")\n    if err != nil {\n        log.Fatalf("failed opening connection to sqlite: %v", err)\n    }\n    defer client.Close()\n\n    // Auto-migrate the schema\n    ctx := context.Background()\n    if err := client.Schema.Create(ctx); err != nil {\n        log.Fatalf("failed creating schema resources: %v", err)\n    }\n\n    // Create a user\n    u, err := client.User.\n        Create().\n        SetName("Alice").\n        SetAge(30).\n        SetEmail("alice@example.com").\n        Save(ctx)\n    if err != nil {\n        log.Fatalf("failed creating user: %v", err)\n    }\n    fmt.Printf("User created: %+v\\n", u)\n\n    // Find a user by name\n    found, err := client.User.\n        Query().\n        Where(user.NameEQ("Alice")).\n        Only(ctx)\n    if e                    

Recommendations