Sequelize 中文API文档-10. Migrations 数据迁移与QueryInterface对象

 2017年06月10日    2448     声明


Sequelize 2.0.0引入了一个新的CLI(命令行工具),其基于gulp并结合sequelize-cligulp-sequelizeCLI用于支持数据迁移和项目引导。通过迁移,可以将现有数据库迁移到另一个状态,反之亦然:这些迁移文件会被保存在迁移文件中,迁移文件描述了怎样到达新状态以及如何恢复更改以返回到迁移前的旧状态。

  1. CLI
  2. 框架
  3. queryInterface对象及功能

1. CLI

1.1 CLI安装

要使用CLI首先要安装相应的包:

$ npm install --save sequelize-cli

当通过-g参数全局安装npm包时,可以在命令行中通过sequelize [command]命令来使用CLI工具。而没有使全局安装时,就可以通过node_modules/.bin/sequelize [command]来使用CLI工具。


1.2 CLI使用

当前版本的CLI支持以下命令:

$ sequelize db:migrate        # 运行待迁移
$ sequelize db:migrate:undo   # 恢复上次迁移
$ sequelize help              # 显示本帮助信息
$ sequelize init              # 项目初始化
$ sequelize migration:create  # 生成一个新的迁移文件
$ sequelize version           # 打印版本号


1.3 CLI使用帮助

命令的详细使用方法,可以通过以下方式获取:

$ sequelize help:init
$ sequelize help:db:migrate
$ sequelize help:db:migrate:undo
# etc

例如,当运行上面最后一条命令时,输出如下:

Sequelize [Node: 6.9.1, CLI: 2.7.0, ORM: 4.0.0]

COMMANDS
    sequelize db:migrate:undo -- Reverts a migration.
DESCRIPTION
    Reverts a migration.
OPTIONS
    --env              The environment to run the command in. Default: development
    --coffee           Enables coffee script support. Default: false
    --config           The path to the config file. Default: config/config.json
    --options-path     The path to a JSON file with additional options. Default: none
    --migrations-path  The path to the migrations folder. Default: migrations
    --seeders-path     The path to the seeders folder. Default: seeders
    --models-path      The path to the models folder.Default: models
    --url              The database connection string to use. Alternative to using --config files. Default: none
    --name             Name of the migration to undo.


2. 框架

以下是一个典型的迁移文件框架。所有迁移都在项目顶层一个名为migrations的目录中。sequelize 会生成迁移的框架:

module.exports = {
  up: function(queryInterface, Sequelize) {
    // 转换为新状态的逻辑
  },
 
  down: function(queryInterface, Sequelize) {
    // 恢复修改的逻辑
  }
}

通过queryInterface对象可用来修改数据库。Sequelize对象中存储了数据类型,如:STRINGINTEGERupdown函数需要返回一个Promise。以下是一些示例代码:

module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.dropAllTables();
  }
}

下面章节介绍了queryInterface对象可用一些方法。


3. queryInterface对象及功能

QueryInterfaceSequelize模块的内置类之一,可以通过Sequelize对象(Sequelize实例)的getQueryInterface()方法获取该类的实例(即:queryInterface对象):

var queryInterface = sequelize.getQueryInterface();

通过queryInterface对象中的方法可以对数据进行修改,其中一些方法可以修改数据库的schema

createTable(tableName, attributes, options)

通过传入的表名tableName、属性attributes及其它选项options创建新表。

createTable()方法用于在数据库中创建新表。创建表时可以通过attributes属性定义一些简单或复杂的属性;而options参数,可以用于定义表所使用的编码及引擎等。

queryInterface.createTable(
  'nameOfTheNewTable',
  {
    id: {
      type: Sequelize.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },
    createdAt: {
      type: Sequelize.DATE
    },
    updatedAt: {
      type: Sequelize.DATE
    },
    attr1: Sequelize.STRING,
    attr2: Sequelize.INTEGER,
    attr3: {
      type: Sequelize.BOOLEAN,
      defaultValue: false,
      allowNull: false
    },
    //foreign key usage
    attr4: {
        type: Sequelize.INTEGER,
        references: {
            model: 'another_table_name',
            key: 'id'
        },
        onUpdate: 'cascade',
        onDelete: 'cascade'
    }
  },
  {
    engine: 'MYISAM', // default: 'InnoDB'
    charset: 'latin1' // default: null
  }
)

dropTable(tableName, options)

删除已存在的表

queryInterface.dropTable('nameOfTheExistingTable')

dropAllTables(options)

删除数据库中所有已存在的表

queryInterface.dropAllTables()

renameTable(before, after, options)

重命名已存在的表

queryInterface.renameTable('Person', 'User')
showAllTables(options)

返回数据库中所有已存在的表的表名

queryInterface.showAllTables().then(function(tableNames) {})

describeTable(tableName, options)

返回表描述,即:返回的一个包含所有属性信息的哈希表

queryInterface.describeTable('Person').then(function(attributes) {
  /*
    attributes 结构类似如下:
 
    {
      name: {
        type:         'VARCHAR(255)', // this will be 'CHARACTER VARYING' for pg!
        allowNull:    true,
        defaultValue: null
      },
      isBetaMember: {
        type:         'TINYINT(1)', // this will be 'BOOLEAN' for pg!
        allowNull:    false,
        defaultValue: false
      }
    }
  */
})

addColumn(tableName, attributeName, dataTypeOrOptions, options)

向已存在的表中添加新列,数据类型可以简单或详细定义

queryInterface.addColumn(
  'nameOfAnExistingTable',
  'nameOfTheNewAttribute',
  Sequelize.STRING
)

// or

queryInterface.addColumn(
  'nameOfAnExistingTable',
  'nameOfTheNewAttribute',
  {
    type: Sequelize.STRING,
    allowNull: false
  }
)

// or with an explicit schema:

queryInterface.addColumn({
    tableName: 'Person',
    schema: 'public'
  },
  'signature',
  Sequelize.STRING
)

removeColumn(tableName, attributeName, options)

移除已存在的表中指定的列

queryInterface.removeColumn('Person', 'signature')

// or with an explicit schema:

queryInterface.removeColumn({
  tableName: 'Person',
  schema: 'public'
}, 'signature');

changeColumn(tableName, attributeName, dataTypeOrOptions, options)

修改属性的元数据。可以修改默认值、是否允许空或数据类型,修改时应该确保完全描述了新的数据类型。

queryInterface.changeColumn(
  'nameOfAnExistingTable',
  'nameOfAnExistingAttribute',
  {
    type: Sequelize.FLOAT,
    allowNull: false,
    defaultValue: 0.0
  }
)

renameColumn(tableName, attrNameBefore, attrNameAfter, options)

重命令属性(修改列名)

queryInterface.renameColumn('Person', 'signature', 'sig')

addIndex(tableName, attributes, options)

通过指定的属性向表中索引。当没有传入options时,会自动创建索引名。

// This example will create the index person_firstname_lastname
queryInterface.addIndex('Person', ['firstname', 'lastname'])

// This example will create a unique index with the name SuperDuperIndex using the optional 'options' field.
// Possible options:
// - indicesType: UNIQUE|FULLTEXT|SPATIAL
// - indexName: The name of the index. Default is __
// - parser: For FULLTEXT columns set your parser
// - indexType: Set a type for the index, e.g. BTREE. See the documentation of the used dialect
// - logging: A function that receives the sql query, e.g. console.log
// - where: A hash of attributes to limit your index(Filtered Indexes - MSSQL & PostgreSQL only)
queryInterface.addIndex(
  'Person',
  ['firstname', 'lastname'],
  {
    indexName: 'SuperDuperIndex',
    indicesType: 'UNIQUE'
  }
)

queryInterface.addIndex(
  'Person',
  ['firstname', 'lastname'],
  {
    where: {
      lastname: {
        $ne: null
      }
    }
  }
)

removeIndex(tableName, indexNameOrAttributes, options)

移除表中已存在的索引

queryInterface.removeIndex('Person', 'SuperDuperIndex')

// or

queryInterface.removeIndex('Person', ['firstname', 'lastname'])

addConstraint(tableName, attributes, options)

V4.0.0+

添加一个新约束。

  • tableName - 要添加约束的表的表名
  • attributes - 应用约束的列名数组
  • options - 一个包含约束定义的对象,如:约束名、类型等

options中可用的选项有:

  • type - 约束类型。可用的约束类型有:
    • UNIQUE
    • DEFAULT (MSSQL only)
    • CHECK (MySQL - Ignored by the database engine )
    • FOREIGN KEY
    • PRIMARY KEY
  • name - 约束名。如果不指定,sequelize将根据约束类型、表名、列名自动命名
  • defaultValue - 约束默认值
  • where - 约束检查条件
  • references - Object。指定目标表、列名以创建外键约束
  • references.table - 目标表名或表
  • references.field - 目录列名 Available constraints:
//UNIQUE
queryInterface.addConstraint('Users', ['email'], {
  type: 'unique',
  name: 'custom_unique_constraint_name'
});

//CHECK
queryInterface.addConstraint('Users', ['roles'], {
  type: 'check',
  where: {
    roles: ['user', 'admin', 'moderator', 'guest']
  }
});

//Default - MSSQL only
queryInterface.addConstraint('Users', ['roles'], {
  type: 'default',
  defaultValue: 'guest'
});

//Primary Key
queryInterface.addConstraint('Users', ['username'], {
  type: 'primary key',
  name: 'custom_primary_constraint_name'
});

//Foreign Key
queryInterface.addConstraint('Posts', ['username'], {
  type: 'FOREIGN KEY',
  references: { //Required field
    table: 'target_table_name',
    field: 'target_column_name'
  },
  onDelete: 'cascade',
  onUpdate: 'cascade'
});

removeConstraint(tableName, constraintName, options)

V4.0.0+

移除表中已经存在的约束

queryInterface.removeConstraint('Users', 'my_constraint_name');

showConstraint(tableName, options)

返回表中已经存在的约束列表

V4.0.0+

queryInterface.showConstraint('Users');
// Returns array of objects/constraints