Schema migrations are JSON files gradually describing project schema changes - e.g. new entities or ACL updates.
Creating a diff using
After you update your schema, you need to create a migration for your change, otherwise Contember won't see it.
There is a command to rescue you:
npm run contember migrations:diff <project> <migration name>
Example: creating a diff
npm run contember migrations:diff my-blog add-categories
Name of a migration can only contain alphanumeric letters and a dash
Contember will show you individual migration steps and ask you for confirmation.
You should check the steps with caution, because Contember cannot detect some changes correctly and it may result in a loss of your data. For example when you rename a field it drops the field and creates a new one.
If you have chosen to execute migration, you are done for now. If you haven't, you can check created
.json file and modify migration file manually describing the change more precisely.
Explaining a migration using
You can again verify individual migration steps using
migrations:describe. You can use
--no-sql to alter output of the command.
Example: explaining migrations steps
npm run contember migrations:describe my-blog
Executing migrations using
If you've pulled new migrations from upstream, or you want to execute a migration, you've created, you can apply all pending migrations using
Example: executing migrations
npm run contember migrations:execute my-blog
All the changes will be applied to both Contember schema and PostgreSQL database.
To execute migrations, you need appropriate permissions.
Contember includes constraints to prevent database inconsistencies. Namely:
- you can't change content of executed migration
- you can't execute a migration, which precedes already executed migration
Therefore, you should:
- never modify or delete a migration, which has been executed on live environment,
- ensure, that new migration is always last (e.g. when merging a branch).
Commands for development
During local development, you can bypass some of these checks, even if the migration was locally executed.
Note that all of these commands are available only on local Contember instance and not in production environments.
Amending a migration
Imagine you are developing a new feature. You've already created and applied schema migration. Later, you find you need another schema change related to the previous one.
Instead of creating a new diff, you can use
migrations:amend my-blog command, which updates most recent migration both on disk and on local Contember instance.
Reverting a schema changes and running
migrations:amend results in removing the migration.
Example: amending latest migration
npm run contember migrations:amend my-blog
Example: amending specific migration
You can specify a migration to amend using additional argument.
npm run contember migrations:amend my-blog 2022-01-17-101806-test
If someone else has already run the migration, or it's deployed it won't be possible to execute the amended migration.
Rebasing a migration using
Before merging a branch with a new migration, you might find that a new migration appeared in an upstream.
migrations:rebase my-blog command helps you solve this issue. Just pass names of migrations you need to merge and the command renames migrations on disk and in your local Contember instance.
npm run contember migrations:rebase my-blog 2022-01-17-101806-test
Force execution of out-of-order migrations
When you pull a code from the upstream, there might appear a new migration preceding your local migrations. To bypass this, you can run
migrations:execute command with
Example: force executing
npm run contember migrations:execute my-blog --force
Writing or fixing migrations manually
Usually you don't write migrations from scratch, but sometimes you may want to fix or tweak generated migration. If you open a generated
.json migration file you will see a list of "modifications". Here are some modifications you will probably use if you edit migration file manually:
If you rename an entity, Contember will create a migration which drops an old entity and creates a new one. Using this modification you can say Contember to just rename an existing entity.
This is similar to
updateEntityName modification, but on a field level.
For not null column it might be useful to fill the column, so it won't fail in a runtime.
fillValue: a value with which a column is filled on migration run (it is different from default value which is used at runtime, but if the new column with default value is added it will be used also as
fillValuein generated JSON migration)
copyValue: a name of other column, which value will be copied to a column