全屏浏览
缩小浏览
回到页首

fs项目---->migrate-mongo的使用(一)

TW项目中用的是mongo数据库,数据的迁移也是需求的一部分。这时我们可以使用migrate-mongo在nodejs中方便的进行数据的迁移,以下记录一下使用的过程。

migrate-mongo的使用

全局安装:npm install -g migrate-mongo,在项目中也可以局部安装:npm install migrate-mongo。

运行migrate-mongo,可以看到migrate-mongo支持以下的命令:

  • init    initialize a new migration project
  • create [options] [description] create a new database migration with the provided description
  • up [options] run all unapplied database migrations
  • down [options] undo the last applied database migration
  • status [options] print the changelog of the database

现在我们就来实践一下,来体验migrate-mongo的使用。首先我们创建一个目录,存放migration的脚本。

~/Program/javascript/node/2018-06-07/learn-node/node1> mkdir migrations
~/Program/javascript/node/2018-06-07/learn-node/node1> cd migration

我们的mongodb里面customer表的数据如下:

/* 1 */
{
    "_id" : ObjectId("5b6d4ea91eb211b1c51600f8"),
    "firstName" : "Alice",
    "lastName" : "Smith",
    "_class" : "com.thoughtworks.springcloud.entity.Customer"
}

/* 2 */
{
    "_id" : ObjectId("5b6d4ea91eb211b1c51600f9"),
    "firstName" : "Bob",
    "lastName" : "Smith",
    "_class" : "com.thoughtworks.springcloud.entity.Customer"
}

创建migration的配置文件:migrate-mongo init,生成的config.js内容配置,其中mogodb的地址是本地,数据库名为huhx。

'use strict';
module.exports = {

  mongodb: {
    url: 'mongodb://localhost:27017',
    databaseName: "huhx",

    options: {
      useNewUrlParser: true, // removes a deprecation warning when connecting
      //   connectTimeoutMS: 3600000, // increase connection timeout to 1 hour
      //   socketTimeoutMS: 3600000, // increase socket timeout to 1 hour
    }
  },

  // The migrations dir, can be an relative or absolute path. Only edit this when really necessary.
  migrationsDir: 'migrations',

  // The mongodb collection where the applied changes are stored. Only edit this when really necessary.
  changelogCollectionName: 'changelog',
};

然后我们创建我们的迁移脚本,在表里面加上一个更新lastname=Smith的值为hu。

~/Program/javascript/node/2018-06-07/learn-node/node1/migrations> migrate-mongo create addfullnamefield
Created: migrations/20180915084157-addfullnamefield.js

我们编写20180915084157-addfullnamefield.js的内容如下:

'use strict';
module.exports = {
    up(db) {
        // TODO write your migration here
        const customerList = db.collection('customer').find({firstName: 'Alice'});
        return customerList.forEach(item => {
            const fullName = `${item.firstName} ${item.lastName}`;
            db.collection('customer').updateOne({_id: item._id}, {$set: {fullName: fullName}}, {multi: 1});
        });
    },

    down(db) {
        // TODO write the statements to rollback your migration (if possible)
        return db.collection('customer').updateMany({firstName: 'Alice'}, {$unset: {fullName: ''}});
    }
};

此时我们可以使用migrate-mongo status命令来查看migrate的状态:

img

运行migrate-mongo up正式执行migration。如下所示

~/Program/javascript/node/2018-06-07/learn-node/node1/migrations> migrate-mongo up
MIGRATED UP: 20180915084157-addfullnamefield.js

此时我们可以看到在huhx的数据库,可以看到changelog的collection。里面的内容如下:

{
    "_id" : ObjectId("5b9ccd21adbd49b60990f0b8"),
    "fileName" : "20180915084157-addfullnamefield.js",
    "appliedAt" : ISODate("2018-09-15T09:13:05.272Z")
}

而且我们的customer中的数据,也相应的得到了迁移处理。

/* 1 */
{
    "_id" : ObjectId("5b6d4ea91eb211b1c51600f8"),
    "firstName" : "Alice",
    "lastName" : "Smith",
    "_class" : "com.thoughtworks.springcloud.entity.Customer",
    "fullName" : "Alice Smith"
}

/* 2 */
{
    "_id" : ObjectId("5b6d4ea91eb211b1c51600f9"),
    "firstName" : "Bob",
    "lastName" : "Smith",
    "_class" : "com.thoughtworks.springcloud.entity.Customer"
}

需要注意的是关于up的函数:

  • function up(db) { /* */ } should return Promise
  • function up(db, next) { /* */ } should callback next

如果我们要撤销修改,我们可以执行migrate-mongo downw命令,也就是执行我们定义的down()函数的内容,产生的效果是customer表中fullName字段删除了,而且查看changelog数据也是为空。再次运行migrate-mongo status查看状态:

img

最后我们也可以指定其它的配置文件,使用-f 参数。

img

如果我们的addfullnamefield.js文件改变了,想要重新migrate up(已经up过了)。做法是在数据库changelog中删除记录或者是重新写一个脚本,再跑一次migrate-mongo up命令。


友情链接

posted @ 2018-09-15 17:39  huhx  阅读(1096)  评论(0编辑  收藏  举报