mirror of
https://github.com/ent/ent.git
synced 2026-03-05 19:35:23 +03:00
doc: explain how to use extensions in migrations (#4140)
This commit is contained in:
@@ -218,6 +218,23 @@ atlas schema apply \
|
||||
--url "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable"
|
||||
```
|
||||
|
||||
Or, using the [Atlas Go SDK](https://github.com/ariga/atlas-go-sdk):
|
||||
|
||||
```go
|
||||
ac, err := atlasexec.NewClient(".", "atlas")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize client: %w", err)
|
||||
}
|
||||
// Automatically update the database with the desired schema.
|
||||
// Another option, is to use 'migrate apply' or 'schema apply' manually.
|
||||
if _, err := ac.SchemaApply(ctx, &atlasexec.SchemaApplyParams{
|
||||
Env: "local",
|
||||
URL: "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable",
|
||||
}); err != nil {
|
||||
log.Fatalf("failed to apply schema changes: %w", err)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
The code for this guide can be found in [GitHub](https://github.com/ent/ent/tree/master/examples/compositetypes).
|
||||
@@ -185,6 +185,23 @@ atlas schema apply \
|
||||
--url "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable"
|
||||
```
|
||||
|
||||
Or, using the [Atlas Go SDK](https://github.com/ariga/atlas-go-sdk):
|
||||
|
||||
```go
|
||||
ac, err := atlasexec.NewClient(".", "atlas")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize client: %w", err)
|
||||
}
|
||||
// Automatically update the database with the desired schema.
|
||||
// Another option, is to use 'migrate apply' or 'schema apply' manually.
|
||||
if _, err := ac.SchemaApply(ctx, &atlasexec.SchemaApplyParams{
|
||||
Env: "local",
|
||||
URL: "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable",
|
||||
}); err != nil {
|
||||
log.Fatalf("failed to apply schema changes: %w", err)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
The code for this guide can be found in [GitHub](https://github.com/ent/ent/tree/master/examples/domaintypes).
|
||||
@@ -179,6 +179,23 @@ atlas schema apply \
|
||||
--url "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable"
|
||||
```
|
||||
|
||||
Or, using the [Atlas Go SDK](https://github.com/ariga/atlas-go-sdk):
|
||||
|
||||
```go
|
||||
ac, err := atlasexec.NewClient(".", "atlas")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize client: %w", err)
|
||||
}
|
||||
// Automatically update the database with the desired schema.
|
||||
// Another option, is to use 'migrate apply' or 'schema apply' manually.
|
||||
if _, err := ac.SchemaApply(ctx, &atlasexec.SchemaApplyParams{
|
||||
Env: "local",
|
||||
URL: "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable",
|
||||
}); err != nil {
|
||||
log.Fatalf("failed to apply schema changes: %w", err)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
The code for this guide can be found in [GitHub](https://github.com/ent/ent/tree/master/examples/enumtypes).
|
||||
222
doc/md/migration/extension.mdx
Normal file
222
doc/md/migration/extension.mdx
Normal file
@@ -0,0 +1,222 @@
|
||||
---
|
||||
title: Using Postgres Extensions in Ent Schema
|
||||
id: extension
|
||||
slug: extensions
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import InstallationInstructions from '../components/_installation_instructions.mdx';
|
||||
|
||||
|
||||
[Postgres extensions](https://www.postgresql.org/docs/current/sql-createextension.html) are add-on modules that extend
|
||||
the functionality of the database by providing new data types, operators, functions, procedural languages, and more.
|
||||
|
||||
This guide explains how to define a schema field that uses a data type provided by the PostGIS extension, and configure
|
||||
the schema migration to manage both Postgres extension installations and the Ent schema as a single migration unit using
|
||||
Atlas.
|
||||
|
||||
:::info [Atlas Pro Feature](https://atlasgo.io/features#pro-plan)
|
||||
Atlas support for [Extensions](https://atlasgo.io/atlas-schema/hcl#extension) is available exclusively to Pro users.
|
||||
To use this feature, run:
|
||||
```
|
||||
atlas login
|
||||
```
|
||||
:::
|
||||
|
||||
## Install Atlas
|
||||
|
||||
<InstallationInstructions />
|
||||
|
||||
## Login to Atlas
|
||||
|
||||
```shell
|
||||
$ atlas login a8m
|
||||
//highlight-next-line-info
|
||||
You are now connected to "a8m" on Atlas Cloud.
|
||||
```
|
||||
|
||||
## Composite Schema
|
||||
|
||||
An `ent/schema` package is mostly used for defining Ent types (objects), their fields, edges and logic. Extensions like
|
||||
`postgis` or `hstore` do not have representation in Ent schema. A Postgres extension can be installed once in your
|
||||
Postgres database, and may be used multiple times in different schemas.
|
||||
|
||||
In order to extend our PostgreSQL schema migration to include both extensions and our Ent types, we configure Atlas to
|
||||
read the state of the schema from a [Composite Schema](https://atlasgo.io/atlas-schema/projects#data-source-composite_schema)
|
||||
data source. Follow the steps below to configure this for your project:
|
||||
|
||||
1\. Create a `schema.sql` that defines the necessary extensions used by your database. In the same way, you can define
|
||||
the extensions in [Atlas Schema HCL language](https://atlasgo.io/atlas-schema/hcl-types#extension):
|
||||
|
||||
<Tabs>
|
||||
<TabItem value={"sql"} label={"Using SQL"}>
|
||||
|
||||
```sql title="schema.sql"
|
||||
-- Install PostGIS extension.
|
||||
CREATE EXTENSION postgis;
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value={"hcl"} label={"Using HCL"}>
|
||||
|
||||
```hcl title="schema.hcl"
|
||||
schema "public" {}
|
||||
|
||||
extension "postgis" {
|
||||
schema = schema.public
|
||||
version = "3.4.2"
|
||||
comment = "PostGIS geometry and geography spatial types and functions"
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
2\. In your Ent schema, define a field that uses the data type provided by the extension. In this example, we use the
|
||||
`GEOMETRY(Point, 4326)` data type provided by the `postgis` extension:
|
||||
|
||||
```go title="ent/schema/user.go" {7-9}
|
||||
// Fields of the User.
|
||||
func (User) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.Bytes("location").
|
||||
// Ideally, we would use a custom GoType
|
||||
// to represent the "geometry" type.
|
||||
SchemaType(map[string]string{
|
||||
dialect.Postgres: "GEOMETRY(Point, 4326)",
|
||||
}),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3\. Create a simple `atlas.hcl` config file with a `composite_schema` that includes both the extensions defined in
|
||||
`schema.sql` and your Ent schema:
|
||||
|
||||
```hcl title="atlas.hcl"
|
||||
data "composite_schema" "app" {
|
||||
# Install extensions first (PostGIS).
|
||||
schema "public" {
|
||||
url = "file://schema.sql"
|
||||
}
|
||||
# Then, load the Ent schema.
|
||||
schema "public" {
|
||||
url = "ent://ent/schema"
|
||||
}
|
||||
}
|
||||
|
||||
env "local" {
|
||||
src = data.composite_schema.app.url
|
||||
dev = "docker://postgis/latest/dev"
|
||||
format {
|
||||
migrate {
|
||||
diff = "{{ sql . \" \" }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
After setting up our composite schema, we can get its representation using the `atlas schema inspect` command, generate
|
||||
schema migrations for it, apply them to a database, and more. Below are a few commands to get you started with Atlas:
|
||||
|
||||
#### Inspect the Schema
|
||||
|
||||
The `atlas schema inspect` command is commonly used to inspect databases. However, we can also use it to inspect our
|
||||
`composite_schema` and print the SQL representation of it:
|
||||
|
||||
```shell
|
||||
atlas schema inspect \
|
||||
--env local \
|
||||
--url env://src \
|
||||
--format '{{ sql . }}'
|
||||
```
|
||||
|
||||
The command above prints the following SQL.
|
||||
|
||||
```sql
|
||||
-- Add new schema named "public"
|
||||
CREATE SCHEMA IF NOT EXISTS "public";
|
||||
-- Set comment to schema: "public"
|
||||
COMMENT ON SCHEMA "public" IS 'standard public schema';
|
||||
-- Create extension "postgis"
|
||||
CREATE EXTENSION "postgis" WITH SCHEMA "public" VERSION "3.4.2";
|
||||
-- Create "users" table
|
||||
CREATE TABLE "public"."users" ("id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "location" public.geometry(point,4326) NOT NULL, PRIMARY KEY ("id"));
|
||||
```
|
||||
|
||||
:::info Extensions Are Database-Level Objects
|
||||
Although the `SCHEMA` argument is supported by the `CREATE EXTENSION` command, it only indicates where the extension's
|
||||
objects will be installed. The extension itself is installed at the database level and cannot be loaded multiple times
|
||||
into different schemas.
|
||||
|
||||
Therefore, to avoid conflicts with other schemas, when working with extensions, the scope of the migration should be set
|
||||
to the database, where objects are qualified with the schema name. Hence, the `search_path` is dropped from the dev-database
|
||||
URL in the `atlas.hcl` file.
|
||||
:::
|
||||
|
||||
#### Generate Migrations For the Schema
|
||||
|
||||
To generate a migration for the schema, run the following command:
|
||||
|
||||
```shell
|
||||
atlas migrate diff \
|
||||
--env local
|
||||
```
|
||||
|
||||
Note that a new migration file is created with the following content:
|
||||
|
||||
```sql title="migrations/20240712090543.sql"
|
||||
-- Create extension "postgis"
|
||||
CREATE EXTENSION "postgis" WITH SCHEMA "public" VERSION "3.4.2";
|
||||
-- Create "users" table
|
||||
CREATE TABLE "public"."users" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"location" public.geometry(point,4326) NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
```
|
||||
|
||||
#### Apply the Migrations
|
||||
|
||||
To apply the migration generated above to a database, run the following command:
|
||||
|
||||
```
|
||||
atlas migrate apply \
|
||||
--env local \
|
||||
--url "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable"
|
||||
```
|
||||
|
||||
:::info Apply the Schema Directly on the Database
|
||||
|
||||
Sometimes, there is a need to apply the schema directly to the database without generating a migration file. For example,
|
||||
when experimenting with schema changes, spinning up a database for testing, etc. In such cases, you can use the command
|
||||
below to apply the schema directly to the database:
|
||||
|
||||
```shell
|
||||
atlas schema apply \
|
||||
--env local \
|
||||
--url "postgres://postgres:pass@localhost:5432/database?sslmode=disable"
|
||||
```
|
||||
|
||||
Or, using the [Atlas Go SDK](https://github.com/ariga/atlas-go-sdk):
|
||||
|
||||
```go
|
||||
ac, err := atlasexec.NewClient(".", "atlas")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize client: %w", err)
|
||||
}
|
||||
// Automatically update the database with the desired schema.
|
||||
// Another option, is to use 'migrate apply' or 'schema apply' manually.
|
||||
if _, err := ac.SchemaApply(ctx, &atlasexec.SchemaApplyParams{
|
||||
Env: "local",
|
||||
URL: "postgres://postgres:pass@localhost:5432/database?sslmode=disable",
|
||||
}); err != nil {
|
||||
log.Fatalf("failed to apply schema changes: %w", err)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
The code for this guide can be found in [GitHub](https://github.com/ent/ent/tree/master/examples/enumtypes).
|
||||
@@ -254,6 +254,23 @@ atlas schema apply \
|
||||
--url "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable"
|
||||
```
|
||||
|
||||
Or, using the [Atlas Go SDK](https://github.com/ariga/atlas-go-sdk):
|
||||
|
||||
```go
|
||||
ac, err := atlasexec.NewClient(".", "atlas")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize client: %w", err)
|
||||
}
|
||||
// Automatically update the database with the desired schema.
|
||||
// Another option, is to use 'migrate apply' or 'schema apply' manually.
|
||||
if _, err := ac.SchemaApply(ctx, &atlasexec.SchemaApplyParams{
|
||||
Env: "local",
|
||||
URL: "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable",
|
||||
}); err != nil {
|
||||
log.Fatalf("failed to apply schema changes: %w", err)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
The code for this guide can be found in [GitHub](https://github.com/ent/ent/tree/master/examples/triggers).
|
||||
@@ -51,6 +51,7 @@ module.exports = {
|
||||
{type: 'doc', id: 'migration/composite', label: 'Composite Types'},
|
||||
{type: 'doc', id: 'migration/domain', label: 'Domain Types'},
|
||||
{type: 'doc', id: 'migration/enum', label: 'Enum Types'},
|
||||
{type: 'doc', id: 'migration/extension', label: 'Extensions'},
|
||||
{type: 'doc', id: 'migration/trigger', label: 'Triggers'},
|
||||
],
|
||||
collapsed: false,
|
||||
|
||||
Reference in New Issue
Block a user