mirror of
https://github.com/therootcompany/golib.git
synced 2026-04-24 04:38:02 +00:00
doc(skills): pgmigrate clarificaton
This commit is contained in:
parent
65432d7c29
commit
c2f5dbeeca
@ -19,19 +19,54 @@ PG_URL='postgres://user:pass@localhost:5432/mydb?sslmode=disable'
|
|||||||
|
|
||||||
## Go library
|
## Go library
|
||||||
|
|
||||||
|
Use `sqlmigrate.Collect(fsys, subpath)` first to parse the embedded files.
|
||||||
|
|
||||||
|
**`//go:embed` constraint:** embed cannot traverse `..`, so the embed directive must live in a package that is at or above the `sql/migrations/` directory. Pass `fs.FS` down to migration helpers rather than embedding inside them.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
|
"embed"
|
||||||
|
"io/fs"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/therootcompany/golib/database/sqlmigrate"
|
"github.com/therootcompany/golib/database/sqlmigrate"
|
||||||
"github.com/therootcompany/golib/database/sqlmigrate/pgmigrate"
|
"github.com/therootcompany/golib/database/sqlmigrate/pgmigrate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed sql/migrations
|
||||||
|
var migrationsFS embed.FS
|
||||||
|
|
||||||
|
func runMigrations(ctx context.Context, pgURL string) error {
|
||||||
|
scripts, err := sqlmigrate.Collect(migrationsFS, "sql/migrations")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// MUST: use pgx.Connect (single conn), not pgxpool.New
|
// MUST: use pgx.Connect (single conn), not pgxpool.New
|
||||||
conn, err := pgx.Connect(ctx, pgURL)
|
conn, err := pgx.Connect(ctx, pgURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer func() { _ = conn.Close(ctx) }()
|
defer func() { _ = conn.Close(ctx) }()
|
||||||
|
|
||||||
runner := pgmigrate.New(conn)
|
runner := pgmigrate.New(conn)
|
||||||
applied, err := sqlmigrate.Latest(ctx, runner, scripts)
|
_, err = sqlmigrate.Latest(ctx, runner, scripts)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key types
|
||||||
|
|
||||||
|
```go
|
||||||
|
// sqlmigrate.Script — one migration pair (up + down SQL + name + ID)
|
||||||
|
// sqlmigrate.Migration — name + ID only (returned by Applied, Latest, etc.)
|
||||||
|
// sqlmigrate.Status — Applied []Migration + Pending []Migration
|
||||||
|
|
||||||
|
scripts, err := sqlmigrate.Collect(fsys, subpath) // parse fs.FS → []Script
|
||||||
|
applied, err := sqlmigrate.Latest(ctx, r, scripts) // apply all pending → []Migration
|
||||||
|
applied, err := sqlmigrate.Up(ctx, r, scripts, n) // apply n migrations
|
||||||
|
rolled, err := sqlmigrate.Down(ctx, r, scripts, n) // roll back n migrations
|
||||||
|
status, err := sqlmigrate.GetStatus(ctx, r, scripts)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Schema multi-tenancy
|
## Schema multi-tenancy
|
||||||
@ -61,4 +96,4 @@ runner := pgmigrate.New(conn)
|
|||||||
- `ON CONFLICT DO NOTHING` for idempotent seeds
|
- `ON CONFLICT DO NOTHING` for idempotent seeds
|
||||||
- String concatenation: `id || CHR(9) || name` (used by sync query)
|
- String concatenation: `id || CHR(9) || name` (used by sync query)
|
||||||
- Timestamps: `TIMESTAMP DEFAULT CURRENT_TIMESTAMP`
|
- Timestamps: `TIMESTAMP DEFAULT CURRENT_TIMESTAMP`
|
||||||
- Error code 42P01 = table doesn't exist (handled automatically by pgmigrate)
|
- Error code 42P01 = table doesn't exist (handled automatically by pgmigrate for initial migration)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user