数据库迁移

迁移是记录的数据库改变,在整个应用程序的开发生命周期中创建,你可以在任何时间点回滚或重新运行。

迁移使团队工作变得更加容易,可以轻松跟踪一个开发人员对数据库架构的更改,然后由组织中的其他开发人员应用。

创建迁移

要使用迁移,必须首先在文件的数组中注册迁移提供程序。 start/app.jsaceProviders 让我们在迁移的帮助下创建一个用户表。

首先,调用 adonis make:migration 命令以创建模式文件:

adonis make:migration users

出现提示时,选择 Create table 选项并按 Enter :

输出
create database/migrations/1502691651527_users_schema.js

新文件(以当前时间戳为前缀)在 database/migrations 目录中创建,可以根据需要进行修改:

数据库/迁移/ ... users_schema.js
'use strict'

const Schema = use('Schema')

class UsersSchema extends Schema {
  up () {
    this.create('users', (table) => {
      table.increments()
      table.timestamps()
    })
  }

  down () {
    this.drop('users')
  }
}

module.exports = UsersSchema

架构文件

模式文件需要两种方法:up和down。

向上() 该up方法用于对表执行操作。它可用于创建新表或更改现有表。

下() 该down方法用于还原方法中应用的更改up。何时up用于创建表,down将用于删除该表。

使用以下代码更新刚刚创建的模式文件:

数据库/迁移/ ... users_schema.js
'use strict'

const Schema = use('Schema')

class UsersSchema extends Schema {
  up () {
    this.create('users', (table) => {
      table.increments()
      table.string('username', 80).notNullable().unique()
      table.string('email', 254).notNullable().unique()
      table.string('password', 60).notNullable()
      table.timestamps()
    })
  }

  down () {
    this.drop('users')
  }
}

module.exports = UsersSchema

上面的示例演示了如何使用模式文件创建/更改数据库表,将不同的列类型/修饰符方法链接在一起以定义方法中各个字段属性的特征up。

列类型/修饰符

有关架构列类型和修饰符方法的完整列表,请参阅 Knex API 文档。

列类型

方法 描述
table.bigInteger(name) 添加长整数列。
table.binary(name, [length]) 添加二进制列。
table.boolean(name) 添加布尔列。
table.date(name) 添加日期列。
table.datetime(name, [precision]) 添加日期时间列。
table.decimal(name, [precision], [scale]) 添加一个十进制列。
table.enu(col, values, [options]) 添加枚举列。
table.float(name, [precision], [scale]) 添加一个浮点列。
table.increments(name) 添加自动递增列。
table.integer(name) 添加整数列。
table.json(name) 添加一个 json 列。
table.string(name, [length=255]) 添加字符串列。
table.text(name, [textType]) 添加文本列。
table.time(name, [precision]) 添加时间列。
table.timestamp(name, [useTz], [precision]) 添加时间戳列。
table.timestamps([useTimestamps], [defaultToNow]) 添加创建/更新的列。
table.uuid(name) 添加一个 uuid 列。

列修饰符

方法 描述
.after(field) 要插入设置列后 field 。
.after() 将列标记为 alter / modify。
.collate(collation) 设置列整理(例如utf8_unicode_ci)。
.comment(value) 设置列注释。
.defaultTo(value) 设置列默认值。
.first() 设置要插入第一个位置的列。
.index([indexName], [indexType]) 将列指定为索引。
.inTable(table) 设置外键(.references)。
.notNullable() 将列设置为非 null 。
.nullable() 将列设置为可为空。
.primary([constraintName]) 将列设置为表的主键。
.references(column) 设置外键列。
.unique() 将列设置为唯一。
.unsigned() 将列设置为无符号(如果为整数)。

多个连接

模式文件可以通过定义 connectiongetter 来使用不同的连接(确保 config/database.js 文件中存在不同的连接):

数据库/迁移/ ... users_schema.js
const Schema = use('Schema')

class UsersSchema extends Schema {
  static get connection () {
    return 'mysql'
  }

  // ...
}

module.exports = UsersSchema

adonis_schema 始终在默认连接数据库中创建数据库表以管理迁移的生命周期(没有覆盖它的选项)。

运行迁移

我们需要调用 migration:run 命令来运行迁移( up 在所有挂起的迁移文件上执行该方法):

adonis migration:run
# 输出
migrate: 1502691651527_users_schema.js
Database migrated successfully in 117 ms

迁移状态

你可以通过运行以下命令来检查所有迁移的状态:

adonis migration:status

该批次值存在,你可以使用在以后的时间限制回滚的参考。 这就是迁移工作的方式:

  • 调用 adonis migration:run 运行所有挂起的模式文件并将它们分配给新批处理。

  • 运行一批迁移文件后,它们不会再次运行。

  • adonis migration:rollback 以相反顺序调用回滚最后一批迁移。

不要在单个模式文件中创建多个表。而是为每个数据库更改创建一个新文件。这样,你可以保持数据库的原子性,并可以回滚到任何版本。

迁移命令

以下是可用迁移命令的列表。

命令列表

命令 描述
make:migration 创建一个新的迁移文件。
migration:run 运行所有挂起的迁移。
migration:rollback 回滚最后一组迁移。
migration:refresh 将所有迁移回滚到0批处理,然后从头开始重新运行它们。
migration:reset 将所有迁移回滚到批处理。
migration:status 获取所有迁移的状态。

命令帮助

有关详细的命令选项,请附加 --help 到每个迁移命令:

adonis migration:run --help
# 输出
Usage:
  migration:run [options]

Options:
  -f, --force   Forcefully run migrations in production
  -s, --silent  Silent the migrations output
  --seed        Seed the database after migration finished
  --log         Log SQL queries instead of executing them

About:
  Run all pending migrations

Schema Table API

下面是可用于与数据库表交互的模式方法的列表。

create

创建一个新的数据库表:

up () {
  this.create('users', (table) => {
  })
}

createIfNotExists

创建一个新的数据库表(仅当它不存在时):

up () {
  this.createIfNotExists('users', (table) => {
  })
}

rename(from, to)

重命名现有数据库表:

up () {
  this.rename('users', 'my_users')
}

drop

删除数据库表:

down () {
  this.drop('users')
}

dropIfExists

删除数据库表(仅当它存在时):

down () {
  this.dropIfExists('users')
}

alter

选择要更改的数据库表:

up () {
  this.alter('users', (table) => {
    // add new columns or remove existing
  })
}

raw

运行任意 SQL 查询:

up () {
  this
    .raw("SET sql_mode='TRADITIONAL'")
    .table('users', (table) => {
      table.dropColumn('name')
      table.string('first_name')
      table.string('last_name')
    })
}

hasTable

返回表是否存在(这是一个 async 方法):

async up () {
  const exists = await this.hasTable('users')

  if (!exists)  {
    this.create('up', (table) => {
    })
  }
}

扩展

以下是运行迁移时可以执行的扩展方法列表。

扩展仅适用于 PostgreSQL 数据库。

createExtension(EXTENSIONNAME)

创建数据库扩展:

class UserSchema {
  up () {
    this.createExtension('postgis')
  }
}

createExtensionIfNotExists(EXTENSIONNAME)

创建数据库扩展(仅当不存在时):

class UserSchema {
  up () {
    this.createExtensionIfNotExists('postgis')
  }
}

dropExtension(extensioName)

删除数据库扩展:

class UserSchema {
  down () {
    this.dropExtension('postgis')
  }
}

dropExtensionIfExists(EXTENSIONNAME)

删除数据库扩展(仅当存在时):

class UserSchema {
  down () {
    this.dropExtensionIfExists('postgis')
  }
}

执行任意代码

在 up 和 down 方法中编写的命令计划在稍后的迁移中执行。

如果需要执行任意数据库命令,请将它们包装在 schedule 函数中:

class UserSchema {
  up () {
    // create new table
    this.create('new_users', (table) => {
    })

    // copy data
    this.schedule(async (trx) => {
      const users = await Database.table('users').transacting(trx)
      await Database.table('new_users').transacting(trx).insert(users)
    })

    // drop old table
    this.drop('users')
  }
}

schedule 方法接收事务对象。在同一事务中运行所有数据库命令很重要,否则你的查询将永久挂起。

Schema Builder API

架构构建器 API 使用 Knex API ,因此请务必阅读其文档以获取更多信息。

fn.now()

Knex 有一个名为 knex.fn.now() 的方法,用于设置数据库字段的当前时间戳。

在 AdonisJs 中,你将此方法引用为 this.fn.now() :

up () {
  this.table('users', (table) => {
    table.timestamp('created_at').defaultTo(this.fn.now())
  })
}
最后一次更新: 7/2/2019, 10:52:13 PM