迁移

迁移是一个由核心团队支持的插件,它通过编写可以使用版本控制系统跟踪的 PHP 文件来帮助您对数据库进行架构更改。

它允许您随着时间的推移来发展数据库表。此插件允许您使用一组直观的 method 来实现数据库更改,而不是在 SQL 中编写架构修改。

此插件是数据库迁移库 Phinx 的包装器。

安装

默认情况下,迁移与默认应用程序框架一起安装。如果您已将其删除并想要重新安装它,您可以在应用程序的 ROOT 目录(包含 composer.json 文件的位置)中运行以下命令:

php composer.phar require cakephp/migrations "@stable"

# Or if composer is installed globally
composer require cakephp/migrations "@stable"

要使用该插件,您需要在应用程序的 config/bootstrap.php 文件中加载它。您可以使用 CakePHP 的插件 shellconfig/bootstrap.php 中加载和卸载插件。

bin/cake plugin load Migrations

或者,您可以通过编辑 src/Application.php 文件并添加以下语句来加载该插件:

$this->addPlugin('Migrations');

// Prior to 3.6.0 you need to use Plugin::load()

此外,您需要在 config/app.php 文件中为您的应用程序配置默认数据库配置,如 数据库配置部分 中所述。

概述

迁移基本上是一个描述对数据库执行的操作更改的单个 PHP 文件。迁移文件可以创建或删除表、添加或删除列、创建索引,甚至将数据插入您的数据库。

以下是一个迁移示例:

<?php
use Migrations\AbstractMigration;

class CreateProducts extends AbstractMigration
{
    /**
     * Change Method.
     *
     * More information on this method is available here:
     * https://book.cakephp.com.cn/phinx/0/en/migrations.html#the-change-method
     * @return void
     */
    public function change()
    {
        $table = $this->table('products');
        $table->addColumn('name', 'string', [
            'default' => null,
            'limit' => 255,
            'null' => false,
        ]);
        $table->addColumn('description', 'text', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('created', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('modified', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->create();
    }
}

此迁移将在您的数据库中添加一个名为 products 的表,并包含以下列定义:

  • id 列,类型为 integer,作为主键

  • name 列,类型为 string

  • description 列,类型为 text

  • created 列,类型为 datetime

  • modified 列,类型为 datetime

提示

名为 id 的主键列将隐式添加。

注意

请注意,此文件描述了应用迁移数据库的外观。此时,您的数据库中不存在 products 表,我们只是创建了一个文件,它既可以创建具有指定列的 products 表,也可以在执行迁移的 rollback 操作时删除它。

在文件创建到 config/Migrations 文件夹后,您将能够执行以下 migrations 命令在您的数据库中创建该表:

bin/cake migrations migrate

以下 migrations 命令将执行 rollback 并从您的数据库中删除该表:

bin/cake migrations rollback

创建迁移

迁移文件存储在应用程序的 config/Migrations 目录中。迁移文件名称以其创建日期为前缀,格式为 YYYYMMDDHHMMSS_MigrationName.php。以下是一些迁移文件名示例:

  • 20160121163850_CreateProducts.php

  • 20160210133047_AddRatingToProducts.php

创建迁移文件最简单的方法是使用 bin/cake bake migration CLI 命令。

请务必阅读官方的 Phinx 文档,以便了解您可以用来编写迁移文件的 method 的完整列表。

注意

在使用 bake 选项时,您仍然可以在运行迁移之前修改迁移,如果需要的话。

语法

bake 命令语法遵循以下格式:

bin/cake bake migration CreateProducts name:string description:text created modified

在使用 bake 创建表、添加列等操作到您的数据库时,您通常需要提供两件事:

  • 您将生成的迁移名称(在本例中为 CreateProducts

  • 将在此迁移中添加或删除的表的列(在本例中为 name:string description:text created modified)。

由于约定,并非所有架构更改都可以通过这些 shell 命令执行。

此外,如果您想完全控制需要执行的操作,可以创建一个空的迁移文件,方法是省略列定义的指定:

bin/cake migrations create MyCustomMigration

迁移文件名

迁移名称可以遵循以下任一模式:

  • (/^(Create)(.*)/) 创建指定的表。

  • (/^(Drop)(.*)/) 删除指定的表。忽略指定的字段参数

  • (/^(Add).*(?:To)(.*)/) 向指定的表添加字段

  • (/^(Remove).*(?:From)(.*)/) 从指定的表中删除字段

  • (/^(Alter)(.*)/) 更改指定的表。它是 CreateTable 和 AddField 的别名。

  • (/^(Alter).*(?:On)(.*)/) 更改指定的表中的字段。

您也可以使用 underscore_form 作为迁移名称,例如 create_products

cakephp/migrations 版本中的新增功能1.5.2

迁移插件 的 v1.5.2 版本开始,迁移文件名将自动转换为驼峰式命名。此版本的插件仅适用于 CakePHP >= 3.1 的版本。在此版本之前的插件版本中,迁移名称将使用下划线形式,例如 20160121164955_create_products.php

警告

迁移名称用作迁移类名,因此如果类名不唯一,可能会与其他迁移发生冲突。在这种情况下,您可能需要在稍后手动覆盖名称,或者只需更改您指定的名称。

列定义

在命令行中使用列时,记住它们遵循以下模式可能很有用:

fieldName:fieldType?[length]:indexType:indexName

例如,以下是指定电子邮件字段的所有有效方式:

  • email:string?

  • email:string:unique

  • email:string?[50]

  • email:string:unique:EMAIL_INDEX

  • email:string[120]:unique:EMAIL_INDEX

在定义 decimal 时,length 可以定义为具有精度和比例,用逗号分隔。

  • amount:decimal[5,2]

  • amount:decimal?[5,2]

fieldType 后面的问号将使该列可为空。

用于 fieldTypelength 参数是可选的,并且应该始终在括号中写。

名为 createdmodified 的字段,以及任何以 _at 后缀结尾的字段,将自动设置为 datetime 类型。

字段类型是由 Phinx 库通用的提供的。它们可以是

  • string

  • text

  • integer

  • biginteger

  • float

  • decimal

  • datetime

  • timestamp

  • time

  • date

  • binary

  • boolean

  • uuid

如果未指定字段类型或设置为无效值,则会有一些启发式方法来选择字段类型。默认字段类型是 string

  • id: integer

  • created, modified, updated: datetime

  • latitude, longitude (或缩写形式 lat, lng): decimal

创建表

你可以使用 bake 来创建表

bin/cake bake migration CreateProducts name:string description:text created modified

上面的命令行将生成一个类似于以下内容的迁移文件

<?php
use Migrations\AbstractMigration;

class CreateProducts extends AbstractMigration
{
    /**
     * Change Method.
     *
     * More information on this method is available here:
     * https://book.cakephp.com.cn/phinx/0/en/migrations.html#the-change-method
     * @return void
     */
    public function change()
    {
        $table = $this->table('products');
        $table->addColumn('name', 'string', [
            'default' => null,
            'limit' => 255,
            'null' => false,
        ]);
        $table->addColumn('description', 'text', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('created', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('modified', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->create();
    }
}

向现有表添加列

如果命令行中的迁移名称形如“AddXXXToYYY”,并且后面跟着列名和类型列表,则会生成一个包含创建列代码的迁移文件

bin/cake bake migration AddPriceToProducts price:decimal[5,2]

执行上面的命令行将生成

<?php
use Migrations\AbstractMigration;

class AddPriceToProducts extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('products');
        $table->addColumn('price', 'decimal', [
            'default' => null,
            'null' => false,
            'precision' => 5,
            'scale' => 2,
        ]);
        $table->update();
    }
}

将列作为索引添加到表

也可以向列添加索引

bin/cake bake migration AddNameIndexToProducts name:string:index

将生成

<?php
use Migrations\AbstractMigration;

class AddNameIndexToProducts extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('products');
        $table->addColumn('name', 'string')
              ->addColumn('email', 'string')
              ->addIndex(['name'])
              // add a unique index:
              ->addIndex('email', ['unique' => true])
              ->update();
    }
}

指定字段长度

cakephp/migrations 版本中的新增功能1.4

如果你需要指定字段长度,可以在字段类型中用括号括起来,例如

bin/cake bake migration AddFullDescriptionToProducts full_description:string[60]

执行上面的命令行将生成

<?php
use Migrations\AbstractMigration;

class AddFullDescriptionToProducts extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('products');
        $table->addColumn('full_description', 'string', [
            'default' => null,
            'limit' => 60,
            'null' => false,
        ])
        ->update();
    }
}

如果没有指定长度,某些类型列的长度将默认为

  • string: 255

  • integer: 11

  • biginteger: 20

更改表中的列

同样,你可以使用命令行生成一个迁移来更改列,如果迁移名称形如“AlterXXXOnYYY”

bin/cake bake migration AlterPriceOnProducts name:float

将生成

<?php
use Migrations\AbstractMigration;

class AlterPriceOnProducts extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('products');
        $table->changeColumn('name', 'float');
        $table->update();
    }
}

从表中删除列

同样,你可以使用命令行生成一个迁移来删除列,如果迁移名称形如“RemoveXXXFromYYY”

bin/cake bake migration RemovePriceFromProducts price

创建文件

<?php
use Migrations\AbstractMigration;

class RemovePriceFromProducts extends AbstractMigration
{
    public function up()
    {
        $table = $this->table('products');
        $table->removeColumn('price')
              ->save();
    }
}

注意

removeColumn 命令不可逆,因此必须在 up 方法中调用。应该在 down 方法中添加相应的 addColumn 调用。

从现有数据库生成迁移

如果你正在处理一个预先存在的数据库,并且想要开始使用迁移,或者将应用程序数据库的初始模式版本控制,你可以运行 migration_snapshot 命令

bin/cake bake migration_snapshot Initial

它将生成一个迁移文件,名为 YYYYMMDDHHMMSS_Initial.php,其中包含数据库中所有表的创建语句。

默认情况下,快照将通过连接到 default 连接配置中定义的数据库来创建。如果你需要从不同的数据源烘焙快照,可以使用 --connection 选项

bin/cake bake migration_snapshot Initial --connection my_other_connection

你也可以通过使用 --require-table 标志来确保快照仅包含你已定义了相应模型类的表

bin/cake bake migration_snapshot Initial --require-table

使用 --require-table 标志时,shell 将遍历你的应用程序 Table 类,并且只会将模型表添加到快照中。

如果你希望为插件烘焙快照,则将隐式应用相同的逻辑。为此,你需要使用 --plugin 选项

bin/cake bake migration_snapshot Initial --plugin MyPlugin

只有定义了 Table 对象模型类的表才会被添加到插件的快照中。

注意

为插件烘焙快照时,迁移文件将在插件的 config/Migrations 目录中创建。

请注意,当你烘焙快照时,它将自动添加到 phinx 日志表中作为已迁移的。

生成两个数据库状态之间的差异

cakephp/migrations 版本中的新增功能1.6.0

你可以使用 migration_diff 烘焙模板生成一个迁移文件,该文件将包含两个数据库状态之间的所有差异。为此,你可以使用以下命令

bin/cake bake migration_diff NameOfTheMigrations

为了从你当前的数据库状态中获得比较点,迁移 shell 将在每次 migraterollback 调用后生成一个“dump”文件。dump 文件是一个包含数据库在特定时间点的完整模式状态的文件。

生成 dump 文件后,你在数据库管理系统中直接进行的所有修改都将添加到当你调用 bake migration_diff 命令时生成的迁移文件中。

默认情况下,差异将通过连接到 default 连接配置中定义的数据库来创建。如果你需要从不同的数据源烘焙差异,可以使用 --connection 选项

bin/cake bake migration_diff NameOfTheMigrations --connection my_other_connection

如果你想要在一个已经具有迁移历史记录的应用程序上使用差异功能,你需要手动创建将用作比较的 dump 文件

bin/cake migrations dump

数据库状态必须与你刚刚迁移所有迁移后一样,然后你才能创建 dump 文件。生成 dump 文件后,你就可以开始在数据库中进行更改,并在需要时使用 bake migration_diff 命令。

注意

迁移 shell 无法检测到列重命名。

命令

migrate : 应用迁移

生成或编写迁移文件后,你需要执行以下命令将更改应用到你的数据库

# Run all the migrations
bin/cake migrations migrate

# Migrate to a specific version using the ``--target`` option
# or ``-t`` for short.
# The value is the timestamp that is prefixed to the migrations file name::
bin/cake migrations migrate -t 20150103081132

# By default, migration files are looked for in the **config/Migrations**
# directory. You can specify the directory using the ``--source`` option
# or ``-s`` for short.
# The following example will run migrations in the **config/Alternate**
# directory
bin/cake migrations migrate -s Alternate

# You can run migrations to a different connection than the ``default`` one
# using the ``--connection`` option or ``-c`` for short
bin/cake migrations migrate -c my_custom_connection

# Migrations can also be run for plugins. Simply use the ``--plugin`` option
# or ``-p`` for short
bin/cake migrations migrate -p MyAwesomePlugin

rollback : 回滚迁移

回滚命令用于撤消此插件执行的先前迁移。它是 migrate 命令的反向操作

# You can rollback to the previous migration by using the
# ``rollback`` command::
bin/cake migrations rollback

# You can also pass a migration version number to rollback
# to a specific version::
bin/cake migrations rollback -t 20150103081132

你也可以像 migrate 命令一样使用 --source--connection--plugin 选项。

status : 迁移状态

状态命令打印所有迁移的列表,以及它们当前的状态。你可以使用此命令来确定哪些迁移已经运行

bin/cake migrations status

你也可以使用 --format 选项(或简写为 -f)以 JSON 格式字符串的形式输出结果

bin/cake migrations status --format json

你也可以像 migrate 命令一样使用 --source--connection--plugin 选项。

mark_migrated : 将迁移标记为已迁移

在 1.4.0 版本中新增。

有时将一组迁移标记为已迁移而无需实际运行它们可能很有用。为此,你可以使用 mark_migrated 命令。该命令与其他命令无缝协作。

你可以使用此命令将所有迁移标记为已迁移

bin/cake migrations mark_migrated

你也可以使用 --target 选项将所有迁移标记为已迁移,直到特定版本

bin/cake migrations mark_migrated --target=20151016204000

如果你不希望在过程中将目标迁移标记为已迁移,你可以使用 --exclude 标志

bin/cake migrations mark_migrated --target=20151016204000 --exclude

最后,如果你希望只将目标迁移标记为已迁移,可以使用 --only 标志

bin/cake migrations mark_migrated --target=20151016204000 --only

你也可以像 migrate 命令一样使用 --source--connection--plugin 选项。

注意

当你使用 cake bake migration_snapshot 命令烘焙快照时,创建的迁移将自动标记为已迁移。

自版本 1.4.0 起弃用: 以下使用该命令的方式已被弃用。仅在使用 < 1.4.0 版本的插件时使用它。

此命令期望迁移版本号作为参数

bin/cake migrations mark_migrated 20150420082532

如果你希望将所有迁移标记为已迁移,可以使用 all 特殊值。如果你使用它,它将将所有找到的迁移标记为已迁移

bin/cake migrations mark_migrated all

seed : 种子数据库

从 1.5.5 版本开始,你可以使用 migrations shell 来种子你的数据库。这利用了 Phinx 库的种子功能。默认情况下,种子文件将在你的应用程序的 config/Seeds 目录中查找。请确保你遵循 Phinx 指示构建你的种子文件

对于迁移,提供了 bake 接口用于种子文件

# This will create a ArticlesSeed.php file in the directory config/Seeds of your application
# By default, the table the seed will try to alter is the "tableized" version of the seed filename
bin/cake bake seed Articles

# You specify the name of the table the seed files will alter by using the ``--table`` option
bin/cake bake seed Articles --table my_articles_table

# You can specify a plugin to bake into
bin/cake bake seed Articles --plugin PluginName

# You can specify an alternative connection when generating a seeder.
bin/cake bake seed Articles --connection connection

cakephp/migrations 版本中的新增功能1.6.4

添加了 --data--limit--fields 选项,用于从数据库中导出数据。

从 1.6.4 版本开始,bake seed 命令允许您使用 --data 标志创建包含从数据库中导出数据的种子文件。

bin/cake bake seed --data Articles

默认情况下,它将导出表中找到的所有行。您可以使用 --limit 选项限制导出的行数。

# Will only export the first 10 rows found
bin/cake bake seed --data --limit 10 Articles

如果您只想在种子文件中包含表中的一部分字段,可以使用 --fields 选项。它将要包含的字段列表作为逗号分隔的字符串。

# Will only export the fields `id`, `title` and `excerpt`
bin/cake bake seed --data --fields id,title,excerpt Articles

提示

当然,您可以在同一个命令调用中使用 --limit--fields 选项。

要为数据库播种,可以使用 seed 子命令。

# Without parameters, the seed subcommand will run all available seeders
# in the target directory, in alphabetical order.
bin/cake migrations seed

# You can specify only one seeder to be run using the `--seed` option
bin/cake migrations seed --seed ArticlesSeed

# You can run seeders from an alternative directory, relative to config
bin/cake migrations seed --source AlternativeSeeds

# You can run seeders from a plugin
bin/cake migrations seed --plugin PluginName

# You can run seeders from a specific connection
bin/cake migrations seed --connection connection

请注意,与迁移不同,种子器不会被跟踪,这意味着同一个种子器可以被应用多次。

从另一个种子器调用种子器

cakephp/migrations 版本中的新增功能1.6.2

通常在播种时,必须遵守插入数据的顺序,以避免遇到约束冲突。由于种子器默认情况下按字母顺序执行,您可以使用 \Migrations\AbstractSeed::call() 方法来定义自己的种子器执行顺序。

use Migrations\AbstractSeed;

class DatabaseSeed extends AbstractSeed
{
    public function run(): void
    {
        $this->call('AnotherSeed');
        $this->call('YetAnotherSeed');

        // You can use the plugin dot syntax to call seeders from a plugin
        $this->call('PluginName.FromPluginSeed');
    }
}

注意

如果您想使用 call() 方法,请确保扩展 Migrations 插件的 AbstractSeed 类。该类是在 1.6.2 版本中添加的。

dump:为 diff 烘焙功能生成转储文件

Dump 命令创建一个文件,用于 migration_diff 烘焙模板。

bin/cake migrations dump

每个生成的转储文件都特定于其生成的连接(并因此而附加后缀)。这允许 bake migration_diff 命令在您的应用程序处理来自不同数据库供应商的多个数据库时正确计算 diff。

转储文件将创建在与您的迁移文件相同的目录中。

你也可以像 migrate 命令一样使用 --source--connection--plugin 选项。

使用迁移进行测试

如果您在应用程序模式中使用迁移,您也可以使用相同的迁移在测试中构建模式。在应用程序的 tests/bootstrap.php 文件中,您可以使用 Migrator 类在运行测试时构建模式。如果现有模式是当前的,Migrator 将使用它,如果数据库中的迁移历史与文件系统中的不同,则所有表将被删除,迁移将从头开始重新运行。

// in tests/bootstrap.php
use Migrations\TestSuite\Migrator;

$migrator = new Migrator();

// Simple setup for with no plugins
$migrator->run();

// Run a non 'test' database
$migrator->run(['connection' => 'test_other']);

// Run migrations for plugins
$migrator->run(['plugin' => 'Contacts']);

// Run the Documents migrations on the test_docs connection.
$migrator->run(['plugin' => 'Documents', 'connection' => 'test_docs']);

如果您需要运行多组迁移,可以按如下方式运行它们。

// Run migrations for plugin Contacts on the ``test`` connection, and Documents on the ``test_docs`` connection
$migrator->runMany([
    ['plugin' => 'Contacts'],
    ['plugin' => 'Documents', 'connection' => 'test_docs']
]);

如果您的数据库还包含应用程序未管理的表(如 PostGIS 创建的表),那么您可以使用 skip 选项将这些表排除在删除和截断操作之外。

$migrator->run(['connection' => 'test', 'skip' => ['postgis*']]);

skip 选项接受一个与 fnmatch() 兼容的模式来排除表,以避免删除和截断操作。

如果您需要查看迁移运行时的额外调试输出,可以启用 debug 级别的记录器。

在插件中使用迁移

插件也可以提供迁移文件。这使得旨在分发的插件更加便携,易于安装。Migrations 插件中的所有命令都支持 --plugin-p 选项,这将把执行范围限定到该插件的迁移。

bin/cake migrations status -p PluginName

bin/cake migrations migrate -p PluginName

在非 shell 环境中运行迁移

cakephp/migrations 版本中的新增功能1.2.0

自从迁移插件 1.2 版本发布以来,您可以直接从应用程序(而非 shell 环境)中使用新的 Migrations 类运行迁移。如果您正在开发 CMS 的插件安装程序,这会很方便。 Migrations 类允许您从迁移 shell 中运行以下命令。

  • migrate

  • rollback

  • markMigrated

  • status

  • seed

每个命令在 Migrations 类中都有一个定义的方法。

以下是如何使用它。

use Migrations\Migrations;

$migrations = new Migrations();

// Will return an array of all migrations and their status
$status = $migrations->status();

// Will return true if success. If an error occurred, an exception will be thrown
$migrate = $migrations->migrate();

// Will return true if success. If an error occurred, an exception will be thrown
$rollback = $migrations->rollback();

// Will return true if success. If an error occurred, an exception will be thrown
$markMigrated = $migrations->markMigrated(20150804222900);

// Will return true if success. If an error occurred, an exception will be thrown
$seeded = $migrations->seed();

这些方法可以接受一个参数数组,这些参数应与命令中的选项匹配。

use Migrations\Migrations;

$migrations = new Migrations();

// Will return an array of all migrations and their status
$status = $migrations->status(['connection' => 'custom', 'source' => 'MyMigrationsFolder']);

您可以传递 shell 命令将接受的任何选项。唯一的例外是 markMigrated 命令,它期望要标记为已迁移的迁移的版本号作为第一个参数。将参数数组作为第二个参数传递给此方法。

可选地,您可以在类的构造函数中传递这些参数。它们将用作默认值,这将避免您在每次方法调用时传递它们。

use Migrations\Migrations;

$migrations = new Migrations(['connection' => 'custom', 'source' => 'MyMigrationsFolder']);

// All the following calls will be done with the parameters passed to the Migrations class constructor
$status = $migrations->status();
$migrate = $migrations->migrate();

如果您需要为某个调用覆盖一个或多个默认参数,可以将它们传递给方法。

use Migrations\Migrations;

$migrations = new Migrations(['connection' => 'custom', 'source' => 'MyMigrationsFolder']);

// This call will be made with the "custom" connection
$status = $migrations->status();
// This one with the "default" connection
$migrate = $migrations->migrate(['connection' => 'default']);

功能标志

Migrations 使用 Phinx,它有一些默认情况下禁用的功能标志,但如果您需要可以使用它们。

  • unsigned_primary_keys:Migrations 应该创建无符号整数作为主键吗?(默认:false

  • column_null_default:Migrations 应该默认创建 null 列吗?(默认:false

  • add_timestamps_use_datetime:Migrations 应该使用 DATETIME 类型列作为 addTimestamps() 添加的列吗?

通过 Configure 设置它们以启用(例如,在 config/app.php 中)。

'Migrations' => [
    'unsigned_primary_keys' => true,
    'column_null_default' => true,
],

有关详细信息,请参阅 Phinx 文档

提示和技巧

创建自定义主键

如果您需要在将新表添加到数据库时避免自动创建 id 主键,可以使用 table() 方法的第二个参数。

<?php
use Migrations\AbstractMigration;

class CreateProductsTable extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('products', ['id' => false, 'primary_key' => ['id']]);
        $table
              ->addColumn('id', 'uuid')
              ->addColumn('name', 'string')
              ->addColumn('description', 'text')
              ->create();
    }
}

以上将创建一个 CHAR(36) id 列,它也是主键。

注意

在命令行上指定自定义主键时,您必须将其标记为 id 字段中的主键,否则您可能会收到有关重复 id 字段的错误,例如。

bin/cake bake migration CreateProducts id:uuid:primary name:string description:text created modified

此外,自 Migrations 1.3 以来,引入了处理主键的新方法。为此,您的迁移类应该扩展新的 Migrations\AbstractMigration 类。您可以在迁移类中指定一个 autoId 属性,并将其设置为 false,这将关闭自动 id 列创建。您需要手动创建将用作主键的列,并将其添加到表声明中。

<?php
use Migrations\AbstractMigration;

class CreateProductsTable extends AbstractMigration
{

    public bool $autoId = false;

    public function up()
    {
        $table = $this->table('products');
        $table
            ->addColumn('id', 'integer', [
                'autoIncrement' => true,
                'limit' => 11
            ])
            ->addPrimaryKey('id')
            ->addColumn('name', 'string')
            ->addColumn('description', 'text')
            ->create();
    }
}

与处理主键的先前方法相比,此方法让您能够更好地控制主键列定义:无符号或否、限制、注释等。

所有烘焙的迁移和快照将在必要时使用这种新方法。

警告

处理主键只能在表创建操作中完成。这是由于插件支持的一些数据库服务器的限制。

排序规则

如果您需要创建一个与数据库默认排序规则不同的排序规则的表,可以使用 table() 方法将其定义为一个选项。

<?php
use Migrations\AbstractMigration;

class CreateCategoriesTable extends AbstractMigration
{
    public function change()
    {
        $table = $this
            ->table('categories', [
                'collation' => 'latin1_german1_ci'
            ])
            ->addColumn('title', 'string', [
                'default' => null,
                'limit' => 255,
                'null' => false,
            ])
            ->create();
    }
}

但是请注意,这只能在表创建时完成:目前无法将具有与表或数据库不同的排序规则的列添加到现有表中。只有 MySQLSqlServer 暂时支持此配置键。

更新列名称和使用 Table 对象

如果您使用 CakePHP ORM Table 对象来操作数据库中的值,同时要重命名或删除列,请确保在 update() 调用后创建 Table 对象的新实例。Table 对象注册表会在 update() 调用后被清除,以便刷新 Table 对象实例化时所反映和存储的架构。

迁移和部署

如果您在部署应用程序时使用此插件,请确保清除 ORM 缓存,以便它更新表的列元数据。否则,您可能会在对这些新列执行操作时遇到有关列不存在的错误。CakePHP 核心包含一个 架构缓存 Shell,您可以使用它来执行此操作

// Prior to 3.6 use orm_cache
bin/cake schema_cache clear

重命名表格

该插件允许您使用 rename() 方法重命名表格。在您的迁移文件中,您可以执行以下操作

public function up()
{
    $this->table('old_table_name')
        ->rename('new_table_name')
        ->update();
}

public function down()
{
    $this->table('new_table_name')
        ->rename('old_table_name')
        ->update();
}

跳过 schema.lock 文件生成

cakephp/migrations 版本中的新增功能1.6.5

为了使 diff 功能正常工作,每次迁移、回滚或烘焙快照时都会生成一个 **.lock** 文件,以跟踪数据库架构在任何给定时间点的状态。例如,在生产环境中部署时,您可以使用上述命令的 --no-lock 选项来跳过此文件生成。

bin/cake migrations migrate --no-lock

bin/cake migrations rollback --no-lock

bin/cake bake migration_snapshot MyMigration --no-lock

IDE 自动完成支持

The IdeHelper 插件 可以帮助您获得对表格、其列名和可能的列类型的更多 IDE 支持。特别是 PHPStorm 理解元信息,可以帮助您自动完成这些操作。