Several databases¶
New in Migrax 0.15.0.
An application that uses more than one database, for example orders and billing, migrates
each of them when it starts. The default database keeps the usual migrax.* settings. Each
further database gets a block migrax.databases.<name>.*:
# The default database: unchanged
migrax.locations=db/migration
# A second database
migrax.databases.billing.datasource=billingDataSource
migrax.databases.billing.locations=db/billing
migrax.databases.billing.placeholders.owner=billing_app
The default database is migrated first, then the others in alphabetical order. Each has its own migration history table, lock and checksums, in its own database.
Settings of a database¶
| Setting | Default | Meaning |
|---|---|---|
datasource |
the database's name | The data source to migrate: see By framework |
locations |
db/<name> |
Migration folders, separated by commas |
java-package |
db.<name> |
Package of Java migrations |
schemas |
none | Schemas to migrate one after another |
placeholders.<key> |
none | Values for ${key} in this database's migrations |
env |
migrax.env |
Environment for migrations marked -- migrax:env |
lock-timeout |
migrax.lock-timeout |
How long to wait while another instance migrates |
resume |
migrax.resume |
Re-run a failed resume-safe migration |
migrate-at-startup |
migrax.migrate-at-startup |
false: report only, as described in Metrics and tracing |
drift.check |
migrax.drift.check |
Compare this database with its snapshot at startup: see Drift at startup |
Folders, Java migrations, schemas and placeholders belong to one database: a further database
never runs the default database's migrations. The defaults db/<name> and db.<name> are kept
apart from db/migration and db.migration on purpose, which is why default and
migration can't be database names; nor can history and pending, the names of folders the
migrax command keeps in .migrax/. Names may contain letters, digits, - and _.
By framework¶
| Framework | datasource names |
Example |
|---|---|---|
| Spring Boot | a DataSource bean |
billingDataSource |
| Quarkus | a named data source (quarkus.datasource.<name>.*) |
billing |
| Micronaut | a data source (datasources.<name>.*) |
billing |
| Helidon | a data source (javax.sql.DataSource.<name>.*) |
billing |
| Jakarta EE | a JNDI name | java:global/jdbc/billing |
An application with two databases defines both DataSource beans; the default database
and JPA use the one marked @Primary:
@Bean
@Primary
@ConfigurationProperties("app.datasource.orders")
DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("app.datasource.billing")
DataSource billingDataSource() {
return DataSourceBuilder.create().build();
}
Every EntityManagerFactory waits until all databases are migrated. JavaMigration beans
belong to the default database; a further database finds its Java migrations in its
java-package.
quarkus.datasource.billing.db-kind=postgresql
quarkus.datasource.billing.jdbc.url=jdbc:postgresql://localhost:5432/billing
migrax.databases.billing.locations=db/billing
The block's name is also the data source's name unless datasource says otherwise. The
migrations are listed when the application is built, so native executables migrate every
database too.
datasources:
billing:
url: jdbc:postgresql://localhost:5432/billing
jpa:
billing:
entity-scan:
packages: com.example.billing
migrax:
databases:
billing:
locations: db/billing
Micronaut starts Hibernate for each data source, so give each one its own jpa.<name>
entities. Migrax creates every configured data source at startup, so a database is migrated
even when nothing uses it yet.
Health and metrics¶
The health checks report every database. The default database keeps its usual details
(applied, pending, problems), and each further one adds its own, such as
billing.pending; the check is UP only when every database is up to date. Spring Boot shows
one entry per database under migrax instead.
Every metric has the tag database: default, or the name of a further database. See
Metrics and tracing.
The command line¶
The migrax command works on one database at a time: the default database, or the one
--database names.
migrax generate --database billing
migrax migrate --database billing
migrax status --database billing
With Maven, pass -Dmigrax.database=billing (for example mvn migrax:status
-Dmigrax.database=billing). In a pipeline, MIGRAX_DATABASE=billing does the same for every
command.
For a further database the command reads:
| What | From |
|---|---|
| Connection | --url, then MIGRAX_DATABASES_BILLING_URL (or ..._URL_FILE), then migrax.databases.billing.url, then the framework's settings of its data source: quarkus.datasource.billing.*, datasources.billing.* (Micronaut) or javax.sql.DataSource.billing.* (Helidon). User and password the same way. Spring Boot has no standard key for a second data source, so set migrax.databases.billing.url, .user and .password |
| Migration folders | migrax.databases.billing.locations, else db/billing, under src/main/resources |
| Entities | migrax.databases.billing.package (or --package), needed by the commands that read entities, such as generate, check and plan |
| Snapshot | .migrax/billing/, next to the default database's .migrax/snapshot.json |
migrax.databases.billing.datasource=billingDataSource
migrax.databases.billing.package=com.shop.billing
migrax.databases.billing.url=jdbc:postgresql://localhost:5432/billing
migrax.databases.billing.user=billing
The default database leaves a further database's package out when it sits inside its own: with
the entity package com.shop, the entities in com.shop.billing belong to billing only. Keep
each database's entities in their own package, the same way the application's JPA setup
separates them.
Each database's settings stay its own: MIGRAX_LOCATIONS, MIGRAX_SCHEMAS and the default
database's placeholders never apply to billing. Its own variables start with
MIGRAX_DATABASES_BILLING_, for example MIGRAX_DATABASES_BILLING_PLACEHOLDERS_OWNER.
Settings for the whole application, such as MIGRAX_ENV, apply to every database unless the
block sets them.