{"id":28700718,"url":"https://github.com/tryghost/knex-migrator","last_synced_at":"2025-06-14T11:32:33.957Z","repository":{"id":12012491,"uuid":"70824735","full_name":"TryGhost/knex-migrator","owner":"TryGhost","description":"DB migration tool for knex.js","archived":false,"fork":false,"pushed_at":"2025-06-07T07:40:51.000Z","size":1739,"stargazers_count":100,"open_issues_count":9,"forks_count":28,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-06-10T07:02:49.204Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TryGhost.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"tryghost","open_collective":"ghost"}},"created_at":"2016-10-13T16:12:22.000Z","updated_at":"2025-06-07T07:40:19.000Z","dependencies_parsed_at":"2024-03-06T11:07:40.912Z","dependency_job_id":"84a6987f-06e9-4767-a2d7-1c88c88fb0c0","html_url":"https://github.com/TryGhost/knex-migrator","commit_stats":{"total_commits":720,"total_committers":27,"mean_commits":"26.666666666666668","dds":0.7,"last_synced_commit":"055ceb8c9e7d862cf3c34dab6df22823fedce70c"},"previous_names":[],"tags_count":124,"template":false,"template_full_name":null,"purl":"pkg:github/TryGhost/knex-migrator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TryGhost%2Fknex-migrator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TryGhost%2Fknex-migrator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TryGhost%2Fknex-migrator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TryGhost%2Fknex-migrator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TryGhost","download_url":"https://codeload.github.com/TryGhost/knex-migrator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TryGhost%2Fknex-migrator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259808781,"owners_count":22914705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-14T11:30:38.157Z","updated_at":"2025-06-14T11:32:33.945Z","avatar_url":"https://github.com/TryGhost.png","language":"JavaScript","funding_links":["https://github.com/sponsors/tryghost","https://opencollective.com/ghost"],"categories":[],"sub_categories":[],"readme":"# knex-migrator\n\nA database migration tool for [knex.js](https://github.com/tgriesser/knex), which supports MySQL and SQlite3.\n\n## Features\n\n- [x] JS API\n- [x] CLI Tool\n- [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))\n- [x] Support for database creation\n- [x] Hooks\n- [x] Rollback to latest version\n- [x] Auto-Rollback on error\n- [x] Database health check\n- [x] Supports transactions\n- [x] Full atomic, support for separate DML/DDL scripts (no autocommit)\n- [x] Migration lock\n- [x] Full debug \u0026 pretty log support\n- [x] Custom migration folder structure\n- [x] Stable (Used in [Ghost](https://github.com/TryGhost/Ghost) for many years in thousands of blogs in production mode)\n\n# Install\n\n`npm install knex-migrator --save`\n\nor\n\n`yarn add knex-migrator`\n\nAdd me to your globals:\n   - `npm install --global knex-migrator`\n\n# Usage\n\n## Pre-word\n\n- Replicas are unsupported, because Knex.js [doesn't support them](https://github.com/tgriesser/knex/issues/2253).\n- Sqlite does **not** support read locks by default. Read [here](https://github.com/TryGhost/knex-migrator/issues/87) why.\n- [Comparison](https://github.com/TryGhost/knex-migrator/issues/119) with other available migration tools.\n- Don't mix DDL/DML statements in a migration script. In MySQL DDL statements use implicit commits.\n- It's highly recommended to write both the `up` and the `down` function to ensure a full rollback.\n- If your process dies while migrations are running, knex-migrator won't be able to release the migration lock.\n  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.\n  You can check the tables `migrations` and `migrations_lock`. The rollback will rollback any migrations which were executed based on your current version.\n\n## Configure knex-migrator\n\nThe tool requires a config file in your project root.\nPlease add a file named `MigratorConfig.js`. Knex-migrator will load the config file.\n\n\n```\nmodule.exports = {\n    database: {\n        client:         String          (Required) ['mysql', 'mysql2', 'sqlite3']\n        connection: {\n            host:       String,         (Required) [e.g. '127.0.0.1']\n            user:       String,         (Required)\n            password:   String,         (Required)\n            charset:    String,         (Optional) [Default: 'utf8mb4']\n            database:   String          (Required)\n        }\n    },\n    migrationPath:      String,         (Required) [e.g. '/var/www/project/migrations']\n    currentVersion:     String,         (Required) [e.g. '2.0']\n    subfolder:          String          (Optional) [Default: 'versions']\n}\n```\n\nPlease take a look at [this real example](https://github.com/TryGhost/Ghost/blob/2.19.3/MigratorConfig.js).\n\n## Folder Structure\n\n```\nproject/\n    migrations/\n        hooks/\n            init/\n                index.js\n                before.js\n                shutdown.js\n            migrate/\n                index.js\n                after.js\n                shutdown.js\n        init/\n            1-add-tables.js\n        versions/\n            1.0/\n                1-add-events-table.js\n                2-normalise-settings.js\n            2.0/\n                1-add-timestamps-columns.js\n            2.1/\n                1-remove-empty-strings.js\n                2-add-webhooks-table.js\n                3-add-permissions.js\n```\n\nPlease take a look at [this real example](https://github.com/TryGhost/Ghost/tree/2.19.3/core/server/data/migrations).\n\n## Hooks\n\nKnex-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).\n\n|hook|description|\n|---|---|\n|before|is called before anything happens|\n|beforeEach| is called before each migration script|\n|after|is called after everything happened|\n|afterEach|is called after each migration script|\n|shutdown|is called before the migrator shuts down|\n\n\n## Migration Files\n\n### Config\nYou can configure each migration script.\n\n```\nmodule.exports.config = {\n  transaction: Boolean\n}\n```\n\n\n### Examples\n```\n\nmodule.exports.up = function(options) {\n  const connection = options.connection;\n\n  ...\n\n  return Promise.resolve();\n};\n\nmodule.exports.down = function(options) {\n  const connection = options.connection;\n\n  ...\n\n  return Promise.resolve();\n}\n```\n\n```\n\nmodule.exports.config = {\n  transaction: true\n};\n\nmodule.exports.up = function(options) {\n  const connection = options.transacting;\n\n  ...\n\n  return Promise.resolve();\n};\n\nmodule.exports.down = function(options) {\n  const connection = options.transacting;\n\n  ...\n\n  return Promise.resolve();\n}\n```\n\n## CLI\n\n### Commands\n\n#### knex-migrator help\n\n```\n$ knex-migrator help\nUsage: knex-migrator [options] [command]\n\nOptions:\n  -v, --version       output the version number\n  -h, --help          output usage information\n\nCommands:\n  init|i [config]     init db\n  migrate|m [config]  migrate db\n  reset|r             reset db\n  health|h            health of db\n  rollback|ro         rollbacks your db\n  help [cmd]          display help for [cmd]\n```\n\n#### knex-migrator health\n\n- Returns the database health/state\n- Based on your current version and your migration scripts\n\n#### knex-migrator init\n\n- Initializes your database based on your init scripts\n- Creates the database if it was not created yet\n\n##### Options\n\n```bash\n# Skips a specific migration script\n--skip\n\n# Runs only a specific migration script\n--only\n\n# Path to MigratorConfig.js\n--mgpath\n```\n\n#### knex-migrator migrate\n\n- Migrates your database to latest version\n- Automatic rollback if an error occurs\n\n##### Options\n\n```bash\n# The version you would like to migrate to\n--v\n\n# Combo Feature to check whether the database was already initialized\n--init\n\n# Force the execution no matter which current version you are on\n--force\n\n# Path to MigratorConfig.js\n--mgpath\n```\n\n#### knex-migrator rollback\n\n- Rolls back your database\n- By default, you can only rollback if the database is locked\n\n##### Options\n\n```bash\n# Ignores the migration lock\n--force\n\n# Version you would like to rollback to\n--v\n```\n\n#### knex-migrator reset\n\n- Resets your database\n- Removes the database\n\n##### Options\n\n```bash\n# Ignores the migration lock\n--force\n```\n\n### Advanced\n\n`DEBUG=knex-migrator:* knex-migrator migrate`\n\n\n## JS API\n\n### Instantiation\n\n```js\nconst KnexMigrator = require('knex-migrator');\n\n# Option 1: Pass path to MigratorConfig.js\nconst knexMigrator = new KnexMigrator({\n    knexMigratorFilePath: process.cwd()\n});\n\n# Option 2: Pass object with config\nconst knexMigrator = new KnexMigrator({\n    knexMigratorConfig: { ... }\n});\n\n```\n\n### Commands\n\n```js\n# Health\nknexMigrator.isDatabaseOK\n\n# Initialise database\nknexMigrator.init\n\n# Migrate database\nknexMigrator.migrate\n\n# Rollback database\nknexMigrator.rollback\n\n# Reset database\nknexMigrator.reset\n```\n\n### Examples\n\n```js\nknexMigrator.isDatabaseOK()\n  .then(function() {\n     // database is OK\n     // initialization \u0026 migrations are not missing\n  })\n  .catch(function(err) {\n      if (err.code === 'DB_NOT_INITIALISED') {\n          return knexMigrator.init();\n      }\n\n      if (err.code === 'DB_NEEDS_MIGRATION') {\n        return knexMigrator.migrate();\n      }\n  });\n\n```\n\n# Test\n\n- `yarn lint` run just eslint\n- `yarn test` run eslint \u0026\u0026 then tests\n- `NODE_ENV=testing-mysql yarn test` to test with MySQL\n\n# Publish\n\n- `yarn ship`\n\n# Copyright \u0026 License\n\nCopyright (c) 2013-2025 Ghost Foundation - Released under the [MIT license](LICENSE).\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftryghost%2Fknex-migrator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftryghost%2Fknex-migrator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftryghost%2Fknex-migrator/lists"}