{"id":13480732,"url":"https://github.com/awapps/mongration","last_synced_at":"2025-03-27T11:30:50.020Z","repository":{"id":2903745,"uuid":"47845009","full_name":"awapps/mongration","owner":"awapps","description":"MongoDB migration framework","archived":false,"fork":false,"pushed_at":"2024-03-20T12:00:30.000Z","size":83,"stargazers_count":85,"open_issues_count":14,"forks_count":24,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-20T14:41:09.488Z","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/awapps.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2015-12-11T18:50:17.000Z","updated_at":"2025-01-18T18:02:54.000Z","dependencies_parsed_at":"2024-06-20T23:22:02.629Z","dependency_job_id":"e381673b-efbe-413c-a98a-a8fbecc05479","html_url":"https://github.com/awapps/mongration","commit_stats":{"total_commits":81,"total_committers":9,"mean_commits":9.0,"dds":"0.33333333333333337","last_synced_commit":"1d889a3c18340ef3fb7e0b2881f484e352f7a192"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awapps%2Fmongration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awapps%2Fmongration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awapps%2Fmongration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awapps%2Fmongration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awapps","download_url":"https://codeload.github.com/awapps/mongration/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245835922,"owners_count":20680292,"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":"2024-07-31T17:00:44.311Z","updated_at":"2025-03-27T11:30:49.703Z","avatar_url":"https://github.com/awapps.png","language":"JavaScript","funding_links":[],"categories":["Libraries"],"sub_categories":["JavaScript"],"readme":"# mongration [![build status](https://travis-ci.org/awapps/mongration.svg?branch=master)](https://travis-ci.org/awapps/mongration) [![NPM version](http://img.shields.io/npm/v/mongration.svg)](https://www.npmjs.org/package/mongration)\n\n\u003e A node.js migration framework for MongoDB.\n\nThis is a javascript framework that connects to a mongoDB and run the migrations following the specified order.\nIt is very different from other migration projects because of: \n* **checksum** — issues an error whenever a change on an already migrated file was changed,\n* **persists migration state** — all migrations are persisted on database,\n* **migration order** — guarantees migration order\n* **replica sets** — replica sets are fully suported,\n* **rollback** — rollback process is automatically started whenever an error happens during a migration,\n* **sync / async migrations** — developers can run multiple migrations in sync or async ways,\n* **multiple databases migrations** — developers can run multiple databases migrations sync / asynchronously\n\n\n**Table of Contents**  \n\n- [Programmatic Usage](#programmatic-usage)\n  - [Configuration](#configuration)\n  - [Creating `Migration` object](#creating-migration-object)\n  - [Creating migration steps](#creating-migration-steps)\n  - [Adding steps to migration](#adding-steps-to-migration)  \n    - [Multiple queries example](#multiple-queries-example)\n  - [Running migrations](#running-migrations)\n    - [Migration outputs](#migration-outputs)\n        - [Status ok](#status-ok)\n        - [Status skipped](#status-skipped)\n        - [Status error](#status-error)\n        - [Status rollback](#status-rollback)\n        - [Status rollback-error](#status-rollback-error)\n        - [Status not-run](#status-not-run)\n- [Command line Usage](#command-line-usage)\n- [Included features](#included-features)\n  - [Checksum](#checksum)\n  - [Migration state persisted](#migration-state-persisted)\n  - [Migration Order](#migration-order)\n  - [Replica set support](#replica-set-support)\n  - [Rollback](#rollback)\n  - [Sync and async migrations](#sync-and-async-migrations)\n    - [Sync migration step](#sync-migration-step)\n    - [Async migration step](#async-migration-step)\n  - [Multiple databases migrations](#multiple-databases-migrations)\n- [License](#license)\n  \n\n\n\n## Programmatic Usage\n\nIt's a regular node module, just `npm install` and `require` it:\n\n\n```bash\n  npm install mongration --save\n```\n\n```javascript\nvar Migration = require('mongration').Migration;\n```\n\n\n### Configuration\n\nThe configuration object is a straightforward javascript object that contains the MongoDb access and the collection that will be used to save the migration state:\n\n```javascript\nmodule.exports = {\n   hosts: 'my.host.com:27017',\n   db: 'mydb',\n   user : 'myuser',\n   password : 'mypass',\n   mongoUri : 'mongodb://myuser:mypass@my.host.com:27017/mydb',\n   migrationCollection: 'migrationversion'\n}\n```\n\nThe **migrationCollection** configuration is **always required**. This is the collection name where the [migration state is persisted](#migration-state-persisted).\n\nYou can either specifiy connection parameters separately, or the entire **mongoUri** with all the connection parameters.\nIf you decide to go with the splitted params, **hosts** parameter is required. \n\nPlease use **user** and **password** params only when authentication is required.\n\n\n### Creating `Migration` object\n\nSimply `require` mongration constructor and initialize it with your [configuration](#configuration):\n\n```javascript\nvar mydbConfig = require('./config');\n\nvar Migration = require('mongration').Migration;\nvar mydbMigration = new Migration(mydbConfig);\n```\n\n\n### Creating migration steps\n\nA migration step is a regular javascript object which has 3 properties: \n* `id` — Migration step ID **must be unique** (**required**): Will be used to save migration state on database\n* `up` — Migration script itself (**required**): Uses MongoDB [native driver](http://mongodb.github.io/node-mongodb-native/) to run commands on database\n* `down` — Rollback script itself (*optional*): Will be used to [Rollback](#rollback) changes in case migration has any error\n\n```javascript\nmodule.exports = {\n    id: '1-step',\n\n    up : function(db, cb){\n        db.collection('testcollection').insert({ name: 'initial-setup' }, cb);\n    },\n\n    down : function(db, cb){\n        db.collection('testcollection').remove({ name: 'initial-setup' }, cb);\n    }\n}\n```\n\nBoth `up` and `down` receive two parameters: **db** (MongoDB connection) and **cb** (a callback function that will tell the framework that the step has been completed with / out errors).\n\n\n### Adding steps to migration\n\n`Migration` object exposes an `add` method which receives both single or bulk migration steps. You must provide the migration file path to this framework so it can read it and run [checksum](#checksum) security routine.\n\nWe suggest [nodejs path module](https://nodejs.org/api/path.html) to discover migration step absolute path:\n\n```javascript\nvar path = require('path');\n\n// adding bulk\nmydbMigration.add([\n    path.join(__dirname, './migrations-folder/1-step.js'),\n    path.join(__dirname, './migrations-folder/2-step.js')\n]);\n\n// adding single\nmydbMigration.add(path.join(__dirname, './migrations-folder/3-step.js'));\n```\n\n\n#### Multiple queries example\n\nThis framework supports multiple queries within the same migration step — developer just needs to handle local callbacks (between queries) and call framework back whenever the whole step is done.\n\nWe strongly suggest you to use [async module](https://www.npmjs.com/package/async) to handle asynchronous javascript. Multiple queries example:\n\n```javascript\nvar async = require('async');\n\nmodule.exports = {\n    id: 'my-migration-step-with-multiple-commands',\n    \n    up : function(db, cb){\n        async.series(\n            [\n                function(_cb){db.collection('testcollection').insert({ name: 'initial-setup' }, _cb)},\n                function(_cb){db.collection('othercollection').insert({ name: 'second-setup' }, _cb)},\n                function(_cb){db.collection('othercollection').insert({ name: 'third-setup' }, _cb)}\n            ],\n            cb\n        );  \n    }\n}\n```\n\n\n### Running migrations\n\nAfter adding all steps to your migration, you simply need to run it like:\n\n```javascript\nmydbMigration.migrate(function(err, results){});\n```\n\nThe `migrate` callback function receives 2 parameters:\n* `err` — Error message (if the migration did not run properly)\n* `results` — A list of status for each migration step. See more on [Migration outputs](#migration-outputs).\n\nFor a complete example, check [samples folder](samples/).\n\n\n#### Migration outputs\n\nAll migration steps will have an output so developers know how *exactly* their migrations were performed.\n\n##### Status ok\nThe migration step was **successfully performed** in the database. This step is saved in the database.\n\n##### Status skipped\nThe migration step was skipped because **it was already performed** in a previous migration. This step was already saved in the database.\n\n##### Status error\nThe migration **step returned an error** and the rollback process was called. The error details are returned on `migration.migrate()` callback as described in [Running migrations](#running-migrations). This step was not saved in the database.\n\n##### Status rollback\nAlthough the migration step was successfully performed, the [rollback](#rollback) process was called due to **an error in a step after this one**. This step is not saved in the database.\n\n##### Status rollback-error\nAn error happened during migration process and **this step rollback process was not successfully completed**. The error details are returned on `migration.migrate()` callback as described in [Running migrations](#running-migrations). This step was not saved in the database - however database may contain unexpected data since rollback was not completely done.\n\n##### Status not-run\nThe migration step **was not processed** because an error happened before getting into this step. This step is not saved in the database.\n\n\n## Command line Usage\n\nRead the [CLI tool docs](bin/README.md).\n\n\n## Included features\n\nThis framework was built focused on solving real problems. For that, we have already included the features below.\n\n\n### Checksum\n\nWhenever a migration step is successfully performed, the step file **checksum** is saved on the database.\n*Checksum* is the sum of all step file characters.\n\nExample:\nIf migration step *1-changed-step-sample* was succesfully run, then a developer changes any part of it and try to run it again, the migration step will have **status : error ** and the exception below will be triggered:\n```javascript\n\"[1-changed-step-sample] was already migrated in a different version. Current version[0685c17d538741a062c488ea776b0576] - Database version[72d9204bee94542118bd99cdde8edc0f]\"\n```\n\n\n### Migration Order\n\nIt makes sure that previsouly ran migrations will be rerun on the same order and, if developers changed the migration order, the migration step will have **status : error ** and the exception below will be triggered:\n```javascript\n\"[1-step-sample] was already migrated on [Sat Dec 19 2015 10:18:27 GMT-0200 (BRST)] in a different order. Database order[1] - Current migration on this order[1-reordered-step-sample]\"\n```\n\n\n### Migration state persisted\n\nThe migration state is saved on the **migrationCollection** defined on [configuration](#configuration):\n```javascript\ndb.migrationversion.find()\n{ \"id\" : \"1-simple-query-sample\", \"checksum\" : \"a10e3030bb9683a971bae1f95b986033\", order : \"0\", \"date\" : ISODate(\"2015-12-18T14:28:38.149Z\") }\n{ \"id\" : \"2-multi-parallel-query\", \"checksum\" : \"3999fbcdf95d4c4a06e839cd0c66ede5\", order : \"1\", \"date\" : ISODate(\"2015-12-18T14:28:38.187Z\") }\n{ \"id\" : \"3-multi-sequential-query\", \"checksum\" : \"1181db9b787251df92fd9fb676da2d76\", order : \"2\", \"date\" : ISODate(\"2015-12-18T14:28:38.287Z\") }\n```\n\nThe framework automatically saves the following data as migration state:\n* `id` — ID defined on each migration step\n* `checksum` — Checksum of migration step file that will be used to compare as part of future migrations\n* `order` — Order the step was run\n* `date` — When the migration step was processed\n\n\n### Replica set support\n\nAs describred above, this framework supports migrations on both MongoDB standalone and replica sets versions. \nTo connect to a replica set, enter your **replicaSet** name and add the replica set **hosts** on your [Configuration](#configuration):\n\n```javascript\nmodule.exports = {\n    //...\n    // with splitted params\n    hosts: 'my.host.com:27017,my.otherhost.com:27018,my.backuphost.com:27019',\n    replicaSet : 'myreplica',\n   \n    // or complete connection string\n    mongoUri: 'mongodb://my.host.com:27017,my.otherhost.com:27018,my.backuphost.com:27019/mydb?replicaSet=myreplica'\n}\n```\n\n\n### Rollback\n\nWhenever an error happens during a migration step, the rollback process is automatically called.\nThe rollback process basically consists in calling `down` method of every step that was previously marked as **ok** or **error** - in other words: Skipped (previously ran steps) migration steps **are not rolled back**.\n\nPlease consider that steps without `down` methods will be automatically skipped when rollback process is called.\nPlease check [Migration outputs](#migration-outputs) to understand how rollback modifies steps' statuses.\n\n\n### Sync and async migrations\n\nDevelopers can run multiple queries (sync or async) as part of the same migration step.\n\n#### Sync migration step\nPlease see below an example on how to run multiple **synchronous** queries as part of one migration step:\n```javascript\nvar async = require('async');\n\nmodule.exports = {\n    id: 'sequential-query',\n\n    up : function(db, cb){\n        async.series(\n            [\n                function(cb){db.collection('testcollection').insert({ name: 'initial-sequential-setup' }, cb)},\n                function(cb){db.collection('testcollection').insert({ name: 'second-sequential-setup' }, cb)},\n                function(cb){db.collection('testcollection').insert({ name: 'third-sequential-setup' }, cb)}\n            ],\n            cb\n        );\n    }\n}\n```\n\n#### Async migration step\nPlease see below an example on how to run multiple **asynchronous** queries as part of one migration step:\n```javascript\nvar async = require('async');\n\nmodule.exports = {\n    id: 'parallel-query',\n\n    up : function(db, cb){\n        async.parallel(\n            [\n                function(cb){db.collection('testcollection').insert({ name: 'initial-parallel-setup' }, cb)},\n                function(cb){db.collection('testcollection').insert({ name: 'second-parallel-setup' }, cb)},\n                function(cb){db.collection('testcollection').insert({ name: 'third-parallel-setup' }, cb)}\n            ],\n            cb\n        );\n    }\n}\n```\n\n\n### Multiple databases migrations\n\nYou have the ability to run migrations in more than one database at the same time. Please check the [Multi DB samples](samples/02-multi-db).\n\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Andre Eberhardt\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawapps%2Fmongration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawapps%2Fmongration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawapps%2Fmongration/lists"}