Skip to content

Migrations

TrailBase provides a schema migration system to coordinate changes across different environments. For example, adding a new table or column may need to happen consistently across multiple environments like dev, CI, pre-prod and production.

On the surface, migrations are simply files containing SQL statements in traildepot/migrations/ following a naming scheme of U<timestamp>__<name>.sql. The quickest way to create a new empty migration is: trail migration, which will create an empty file with the current timestamp. Afterwards you can rename the file and add your SQL, e.g.: CREATE TABLE new_table (id INTEGER PRIMARY KEY) STRICT. Once satisfied, migrations can be applied either by restarting TrailBase or sending a SIGHUP signal to a running instance.

Alternatively, altering the schema via the table explorer in the admin UI will generate migrations for you and instantly apply them.

Schema changes to TABLES or VIEWs exposed as APIs will automatically change the API definition and thus require special diligence. Especially client-server divergence over columns with NOT NULL constraints can lead to breaking API changes. For example, adding a new NOT NULL column w/o a DEFAULT requires all clients going forward to provide said value, otherwise the server will reject the call. Consequently, some API toolkits like protobuf strongly advice against or even disallow required fields. In other words, adding and removing nullable columns is a lot simpler and safer.

It is your responsibility to ensure that all clients are compatible with both the old and new version of the API at the time of the rollout. For changes with required fields, it will often be easier to add a new version of the API - potentially using VIEWs to emulate the old behavior - move your clients over, and ensure that no more out-of-date clients exist that we’re not ok with breaking before removing the old API.

Some schema migration systems allow reverting or undoing migrations. In practice, they are inverse follow-up migration. While this allows reverting schemas to a prior state, it doesn’t allow restoring the actual database state. For example, dropping a table is a destructive operation that results in all of the table’s records being deleted. Reverting the schema will bring back an empty table only.

TrailBase does not provide a builtin revert. Schema migrations are append only and move strictly forward in time. They should always be conducted with great care. If a destructive operations has been rolled out all the way to prod, the data is gone. You can still undo the schema change by manually applying an inverse forward migration, i.e. addin a column or table back, but properly undoing the database state will require a restore from backups.