346 lines
7.7 KiB
Markdown
346 lines
7.7 KiB
Markdown
# knex-migrator
|
|
|
|
A database migration tool for [knex.js](https://github.com/tgriesser/knex), which supports MySQL and SQlite3.
|
|
|
|
## Features
|
|
|
|
- [x] JS API
|
|
- [x] CLI Tool
|
|
- [x] Differentiation between database initialization and migration (Support for a database schema, [like we use in Ghost](https://github.com/TryGhost/Ghost/blob/1.16.2/core/server/data/schema/schema.js))
|
|
- [x] Support for database creation
|
|
- [x] Hooks
|
|
- [x] Rollback to latest version
|
|
- [x] Auto-Rollback on error
|
|
- [x] Database health check
|
|
- [x] Supports transactions
|
|
- [x] Full atomic, support for separate DML/DDL scripts (no autocommit)
|
|
- [x] Migration lock
|
|
- [x] Full debug & pretty log support
|
|
- [x] Custom migration folder structure
|
|
- [x] Stable (Used in [Ghost](https://github.com/TryGhost/Ghost) for many years in thousands of blogs in production mode)
|
|
|
|
# Install
|
|
|
|
`npm install knex-migrator --save`
|
|
|
|
or
|
|
|
|
`yarn add knex-migrator`
|
|
|
|
Add me to your globals:
|
|
- `npm install --global knex-migrator`
|
|
|
|
# Usage
|
|
|
|
## Pre-word
|
|
|
|
- Replicas are unsupported, because Knex.js [doesn't support them](https://github.com/tgriesser/knex/issues/2253).
|
|
- Sqlite does **not** support read locks by default. Read [here](https://github.com/TryGhost/knex-migrator/issues/87) why.
|
|
- [Comparison](https://github.com/TryGhost/knex-migrator/issues/119) with other available migration tools.
|
|
- Don't mix DDL/DML statements in a migration script. In MySQL DDL statements use implicit commits.
|
|
- It's highly recommended to write both the `up` and the `down` function to ensure a full rollback.
|
|
- If your process dies while migrations are running, knex-migrator won't be able to release the migration lock.
|
|
To release to lock you can run `knex-migrator rollback`. **But** it's recommended to check your database first to see in which state it is.
|
|
You can check the tables `migrations` and `migrations_lock`. The rollback will rollback any migrations which were executed based on your current version.
|
|
|
|
## Configure knex-migrator
|
|
|
|
The tool requires a config file in your project root.
|
|
Please add a file named `MigratorConfig.js`. Knex-migrator will load the config file.
|
|
|
|
|
|
```
|
|
module.exports = {
|
|
database: {
|
|
client: String (Required) ['mysql', 'mysql2', 'sqlite3']
|
|
connection: {
|
|
host: String, (Required) [e.g. '127.0.0.1']
|
|
user: String, (Required)
|
|
password: String, (Required)
|
|
charset: String, (Optional) [Default: 'utf8mb4']
|
|
database: String (Required)
|
|
}
|
|
},
|
|
migrationPath: String, (Required) [e.g. '/var/www/project/migrations']
|
|
currentVersion: String, (Required) [e.g. '2.0']
|
|
subfolder: String (Optional) [Default: 'versions']
|
|
}
|
|
```
|
|
|
|
Please take a look at [this real example](https://github.com/TryGhost/Ghost/blob/2.19.3/MigratorConfig.js).
|
|
|
|
## Folder Structure
|
|
|
|
```
|
|
project/
|
|
migrations/
|
|
hooks/
|
|
init/
|
|
index.js
|
|
before.js
|
|
shutdown.js
|
|
migrate/
|
|
index.js
|
|
after.js
|
|
shutdown.js
|
|
init/
|
|
1-add-tables.js
|
|
versions/
|
|
1.0/
|
|
1-add-events-table.js
|
|
2-normalise-settings.js
|
|
2.0/
|
|
1-add-timestamps-columns.js
|
|
2.1/
|
|
1-remove-empty-strings.js
|
|
2-add-webhooks-table.js
|
|
3-add-permissions.js
|
|
```
|
|
|
|
Please take a look at [this real example](https://github.com/TryGhost/Ghost/tree/2.19.3/core/server/data/migrations).
|
|
|
|
## Hooks
|
|
|
|
Knex-migrator offers a couple of hooks, which makes it possible to hook into the migration process. You can create a hook per type: 'init' or 'migrate'. The folder name must be `hooks` and is not configurable. Please create an index.js file to export your functions, see [example](https://github.com/TryGhost/Ghost/blob/2.19.3/core/server/data/migrations/hooks/init/index.js).
|
|
|
|
|hook|description|
|
|
|---|---|
|
|
|before|is called before anything happens|
|
|
|beforeEach| is called before each migration script|
|
|
|after|is called after everything happened|
|
|
|afterEach|is called after each migration script|
|
|
|shutdown|is called before the migrator shuts down|
|
|
|
|
|
|
## Migration Files
|
|
|
|
### Config
|
|
You can configure each migration script.
|
|
|
|
```
|
|
module.exports.config = {
|
|
transaction: Boolean
|
|
}
|
|
```
|
|
|
|
|
|
### Examples
|
|
```
|
|
|
|
module.exports.up = function(options) {
|
|
const connection = options.connection;
|
|
|
|
...
|
|
|
|
return Promise.resolve();
|
|
};
|
|
|
|
module.exports.down = function(options) {
|
|
const connection = options.connection;
|
|
|
|
...
|
|
|
|
return Promise.resolve();
|
|
}
|
|
```
|
|
|
|
```
|
|
|
|
module.exports.config = {
|
|
transaction: true
|
|
};
|
|
|
|
module.exports.up = function(options) {
|
|
const connection = options.transacting;
|
|
|
|
...
|
|
|
|
return Promise.resolve();
|
|
};
|
|
|
|
module.exports.down = function(options) {
|
|
const connection = options.transacting;
|
|
|
|
...
|
|
|
|
return Promise.resolve();
|
|
}
|
|
```
|
|
|
|
## CLI
|
|
|
|
### Commands
|
|
|
|
#### knex-migrator help
|
|
|
|
```
|
|
$ knex-migrator help
|
|
Usage: knex-migrator [options] [command]
|
|
|
|
Options:
|
|
-v, --version output the version number
|
|
-h, --help output usage information
|
|
|
|
Commands:
|
|
init|i [config] init db
|
|
migrate|m [config] migrate db
|
|
reset|r reset db
|
|
health|h health of db
|
|
rollback|ro rollbacks your db
|
|
help [cmd] display help for [cmd]
|
|
```
|
|
|
|
#### knex-migrator health
|
|
|
|
- Returns the database health/state
|
|
- Based on your current version and your migration scripts
|
|
|
|
#### knex-migrator init
|
|
|
|
- Initializes your database based on your init scripts
|
|
- Creates the database if it was not created yet
|
|
|
|
##### Options
|
|
|
|
```bash
|
|
# Skips a specific migration script
|
|
--skip
|
|
|
|
# Runs only a specific migration script
|
|
--only
|
|
|
|
# Path to MigratorConfig.js
|
|
--mgpath
|
|
```
|
|
|
|
#### knex-migrator migrate
|
|
|
|
- Migrates your database to latest version
|
|
- Automatic rollback if an error occurs
|
|
|
|
##### Options
|
|
|
|
```bash
|
|
# The version you would like to migrate to
|
|
--v
|
|
|
|
# Combo Feature to check whether the database was already initialized
|
|
--init
|
|
|
|
# Force the execution no matter which current version you are on
|
|
--force
|
|
|
|
# Path to MigratorConfig.js
|
|
--mgpath
|
|
```
|
|
|
|
#### knex-migrator rollback
|
|
|
|
- Rolls back your database
|
|
- By default, you can only rollback if the database is locked
|
|
|
|
##### Options
|
|
|
|
```bash
|
|
# Ignores the migration lock
|
|
--force
|
|
|
|
# Version you would like to rollback to
|
|
--v
|
|
```
|
|
|
|
#### knex-migrator reset
|
|
|
|
- Resets your database
|
|
- Removes the database
|
|
|
|
##### Options
|
|
|
|
```bash
|
|
# Ignores the migration lock
|
|
--force
|
|
```
|
|
|
|
### Advanced
|
|
|
|
`DEBUG=knex-migrator:* knex-migrator migrate`
|
|
|
|
|
|
## JS API
|
|
|
|
### Instantiation
|
|
|
|
```js
|
|
const KnexMigrator = require('knex-migrator');
|
|
|
|
# Option 1: Pass path to MigratorConfig.js
|
|
const knexMigrator = new KnexMigrator({
|
|
knexMigratorFilePath: process.cwd()
|
|
});
|
|
|
|
# Option 2: Pass object with config
|
|
const knexMigrator = new KnexMigrator({
|
|
knexMigratorConfig: { ... }
|
|
});
|
|
|
|
```
|
|
|
|
### Commands
|
|
|
|
```js
|
|
# Health
|
|
knexMigrator.isDatabaseOK
|
|
|
|
# Initialise database
|
|
knexMigrator.init
|
|
|
|
# Migrate database
|
|
knexMigrator.migrate
|
|
|
|
# Rollback database
|
|
knexMigrator.rollback
|
|
|
|
# Reset database
|
|
knexMigrator.reset
|
|
```
|
|
|
|
### Examples
|
|
|
|
```js
|
|
knexMigrator.isDatabaseOK()
|
|
.then(function() {
|
|
// database is OK
|
|
// initialization & migrations are not missing
|
|
})
|
|
.catch(function(err) {
|
|
if (err.code === 'DB_NOT_INITIALISED') {
|
|
return knexMigrator.init();
|
|
}
|
|
|
|
if (err.code === 'DB_NEEDS_MIGRATION') {
|
|
return knexMigrator.migrate();
|
|
}
|
|
});
|
|
|
|
```
|
|
|
|
# Test
|
|
|
|
- `yarn lint` run just eslint
|
|
- `yarn test` run eslint && then tests
|
|
- `NODE_ENV=testing-mysql yarn test` to test with MySQL
|
|
|
|
# Publish
|
|
|
|
- `yarn ship`
|
|
|
|
# Copyright & License
|
|
|
|
Copyright (c) 2013-2023 Ghost Foundation - Released under the [MIT license](LICENSE).
|
|
|
|
|
|
|
|
|
|
|
|
|