`besu generate`
besu generate introspects the database, diffs it against a schema snapshot, and writes the
statements into a numbered SQL file. It is the step between changing a struct and applying a
reviewed migration.
--database also reads DATABASE_URL. Both --database and --schema are required; the
defaults above apply to --out and --name.
Producing the snapshot
The snapshot is the desired state, so it comes from your code rather than from the database:
Schema::from_defs(..) with Schema::save is the same thing when you already have a
Schema value. The file is the IR from the overview.
Running it
If the database already matches the snapshot, nothing is written:
That message is not an error, and the exit status is zero.
What it writes
The filename is {version:04}_{name}.sql. The version is one more than the highest numeric
prefix already in the directory, scanning every entry, so 0007_... and 7_... both count
as seven. The name is --name with spaces turned into underscores and lowercased; other
punctuation is left alone.
Every file starts with the same two lines:
A -- warning is added when the dialect reports that it cannot change a column in place and
the plan contains an AlterColumn. None of the three shipped dialects takes that path: SQLite
rebuilds the table and reports that it can, so its generated files carry the standard header
and nothing more.
Each rendered statement follows on its own line, terminated with ;.
What it does not do
- It does not write a down migration.
generatehas no way to invent the inverse of a dropped column, so the.down.sqlis yours. - It does not update the journal. Generating a file does not mark it applied.
- It does not filter by safety. A
DropColumnorDropTableis written like anything else. - It does not read the migration files. The diff is always snapshot against live database; the directory is scanned only for the next version number.
Gotchas
- Run it against a database at the current migration version. If earlier migrations have not been applied, the generated file repeats their changes under a new version.
- A snapshot from
besu pullcontains the database. Diffing a pulled snapshot against the same database produces an empty file, which is a useful check but not a migration. - Generating twice without applying writes two files with the same content. The second version number is higher; neither knows about the other.
- The name is not sanitised beyond spaces and case.
--name "add-index"produces0002_add-index.sql. - A destructive statement in the file still runs.
besu migratedoes not refuse it; onlypushhas a safety check. - A SQLite
AlterColumnis a table rebuild. The file creates a new table, copies the rows, drops the old one and renames; a trigger is not recreated. The header does not warn, because SQLite reports that it can alter the column.
