Zero Schema

Zero has first-class support for robust schema migrations.

Demo

Overview

When zero-cache first runs against your upstream Postgres database it adds a schemaVersions table to the zero Postgres schema:

\d zero."schemaVersions"
+---------------------+---------+------------------------+
| Column              | Type    | Modifiers              |
|---------------------+---------+------------------------|
| minSupportedVersion | integer |                        |
| maxSupportedVersion | integer |                        |
| lock                | boolean |  not null default true |
+---------------------+---------+------------------------+

> select * from zero."schemaVersions";
+---------------------+---------------------+------+
| minSupportedVersion | maxSupportedVersion | lock |
|---------------------+---------------------+------|
| 1                   | 1                   | True |
+---------------------+---------------------+------+

This table only ever has one row in it, and the two values represent the the range of schema versions currently supported by the database.

The client schema also has a version field:

export const schema = createSchema({
  version: 1,
  tables: {
    user: userSchema,
  },
});

The zero.schemaVersions table is intended to be updated as part of your existing schema migration process.

General Schema Change Process

Like other database-backed applications, Zero schema migration generally follow an “expand/migrate/contract” pattern:

  • Determine the schemaVersion to use for this schema change, lets call it N.
  • Implement and run an “expand” migration on the backend that is backwards compatible with existing schemas. Add new rows, tables, as well as any defaults and triggers needed for backwards compatibility. At the same time update the maxSupportedVersion to N.
  • Update and deploy the client app.
    • Update its schema and schemaVersion.
    • Update app to use new schema.
  • Optionally, after some grace period, implement and run a “contract” migration on the backend, deleting any obsolete rows/tables, at the same time update the minSupportedVersion to N.