# `jadpo migrate`

Write and apply migrations.

Keep the database in step with the entities (area 5). `new` compares the entities with the latest migration's snapshot and writes the next folder in database/migrations/: the whole schema as snapshot.json, the SQL that gets there as postgres.sql, and changes.jadpo when a change needs a decision, such as a value for existing rows; once the decisions are written, `new` again finishes it. With --drop it removes a retired field or entity for good, once a person accepts it. `apply` runs a database's pending migrations, each in a transaction, and a computed backfill in batches, each in its own, carrying on where a stopped run left off; `status` lists the migrations and, with --url, which a database has applied. Until configuration gives each connection its URL, --url names the database.

```text
jadpo migrate <action> [purpose]
```

## Arguments

- `action`: What to do
- `purpose` (optional): What a new migration does, in lower_snake_case

## Flags

- `--url <url>`: The PostgreSQL database to apply to or read
- `--store <name>`: Which store that database is
- `--drop <name>`: A retired field or entity to remove

## On every command

- `--json`: Print data for tools instead of text
- `--full`: Show everything a report shortens
- `--help`: Show every flag, with examples
- `--color <when>`: Choose when to use colour

`jadpo migrate --json` writes one JSON document to standard output instead of text, with the same exit code. The document has `schemaVersion`, `command` (`"migrate"`), `ok`, `data` (what the command produced, `null` when it failed) and `diagnostics` (each error with its `rule`, `reason`, `next` and `help`). A command that needs a terminal refuses `--json` and names the flags that do the same job.

## Examples

```text
# Write the migration for a new field
jadpo migrate new add_rating
# Finish the latest migration once its decisions are written
jadpo migrate new
# Remove a retired field and its data for good
jadpo migrate new drop_rating --drop Review.rating
# Apply the pending migrations to a database
jadpo migrate apply --url postgresql://localhost/shop
# List the migrations and which a database has applied
jadpo migrate status --url postgresql://localhost/shop
```

## Errors

- [`cli.migrate_arguments`](/docs/errors/cli.migrate_arguments.md): A `jadpo migrate` command names no action, one it doesn't have, a purpose for an action that takes none, or a `--drop` of what isn't retired
- [`migration.apply_failed`](/docs/errors/migration.apply_failed.md): Applying the project's migrations to a database stopped at a step that failed
- [`migration.drop_not_accepted`](/docs/errors/migration.drop_not_accepted.md): A migration removes data, and no acceptance in the project says a person agreed to it
- [`migration.store_diverged`](/docs/errors/migration.store_diverged.md): The migrations a database has applied don't match the project's: one has changed since it ran, the project doesn't have one, or one comes out of order
- [`migration.extension_missing`](/docs/errors/migration.extension_missing.md): The project's migrations need a PostgreSQL extension, such as pgvector, that the database server doesn't offer or that the role applying them can't create
- [`migration.extension_outdated`](/docs/errors/migration.extension_outdated.md): The database server's PostgreSQL extension, such as pgvector, is older than the project's migrations and queries need
- [`toolchain.artifact_write_failed`](/docs/errors/toolchain.artifact_write_failed.md): A file Jadpo writes for you, such as a record, couldn't be written, usually because it or its folder is read-only
- [`toolchain.not_built_yet`](/docs/errors/toolchain.not_built_yet.md): Operation is declared but not built yet
- [`toolchain.project_not_found`](/docs/errors/toolchain.project_not_found.md): You ran a command that works on a project in a folder with no `app.jadpo`, in it or in any folder above it
