数据库迁移

迁移是您以结构化和有组织的方式更改数据库的便捷方法。您可以手动编辑 SQL 片段,但您将负责告诉其他开发人员他们需要运行这些片段。您还必须跟踪下次部署时哪些更改需要针对生产机器运行。

数据库表 **migrations** 跟踪哪些迁移已经运行,因此您只需确保您的迁移到位并运行 spark migrate 命令即可将数据库更新到最新状态。您也可以使用 spark migrate --all 来包含来自所有命名空间的迁移。

迁移文件名

每个迁移都以数字顺序向前或向后运行,具体取决于所采用的方法。每个迁移都使用创建迁移时的日期时间戳进行编号,格式为 **YYYY-MM-DD-HHIISS**(例如,**2012-10-31-100537**)。这有助于在团队环境中工作时防止编号冲突。

在迁移文件名前缀添加迁移编号,后面跟着一个下划线和迁移的描述性名称。年份、月份和日期可以用连字符、下划线或根本不分隔。例如

  • 2012-10-31-100538_AlterBlogTrackViews.php

  • 2012_10_31_100539_AlterBlogAddTranslations.php

  • 20121031100537_AddBlog.php

创建迁移

这将是新网站的第一个迁移,该网站有一个博客。所有迁移都位于 **app/Database/Migrations/** 目录中,并具有诸如 **2022-01-31-013057_AddBlog.php** 之类的名称。

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddBlog extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'blog_id' => [
                'type'           => 'INT',
                'constraint'     => 5,
                'unsigned'       => true,
                'auto_increment' => true,
            ],
            'blog_title' => [
                'type'       => 'VARCHAR',
                'constraint' => '100',
            ],
            'blog_description' => [
                'type' => 'TEXT',
                'null' => true,
            ],
        ]);
        $this->forge->addKey('blog_id', true);
        $this->forge->createTable('blog');
    }

    public function down()
    {
        $this->forge->dropTable('blog');
    }
}

数据库连接和数据库 Forge 类都可通过 $this->db$this->forge 分别访问。

或者,您可以使用命令行调用来生成一个骨架迁移文件。有关更多详细信息,请参阅 命令行工具 中的 **make:migration**。

注意

由于迁移类是 PHP 类,因此每个迁移文件中的类名必须是唯一的。

外键

当您的表包含外键时,迁移在您尝试删除表和列时经常会导致问题。要临时绕过运行迁移时的外键检查,请使用数据库连接上的 disableForeignKeyChecks()enableForeignKeyChecks() 方法。

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddBlog extends Migration
{
    public function up()
    {
        $this->db->disableForeignKeyChecks();

        // Migration rules would go here..

        $this->db->enableForeignKeyChecks();
    }
}

数据库组

迁移只会针对单个数据库组运行。如果在 **app/Config/Database.php** 中定义了多个组,则默认情况下它将针对与该配置文件中指定的 $defaultGroup 相同的组运行。

有时您可能需要为不同的数据库组使用不同的模式。也许您有一个数据库用于所有常规网站信息,而另一个数据库用于关键任务数据。

您可以通过在迁移中设置 $DBGroup 属性来确保迁移仅针对正确的组运行。此名称必须与数据库组的名称完全匹配。

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddBlog extends Migration
{
    protected $DBGroup = 'alternate_db_group';

    public function up()
    {
        // ...
    }

    public function down()
    {
        // ...
    }
}

注意

跟踪哪些迁移已运行的 **migrations** 表将始终在默认数据库组中创建。

命名空间

迁移库可以使用 $psr4 属性自动扫描您在 **app/Config/Autoload.php** 中定义的所有命名空间,或从 Composer 等外部来源加载的命名空间,以匹配目录名称。它将包含在 **Database/Migrations** 中找到的所有迁移。

每个命名空间都有自己的版本序列,这将帮助您升级和降级每个模块(命名空间)而不会影响其他命名空间。

例如,假设我们在 Autoload 配置文件中定义了以下命名空间

<?php

$psr4 = [
    'App'       => APPPATH,
    'MyCompany' => ROOTPATH . 'MyCompany',
];

这将查找位于 **APPPATH/Database/Migrations** 和 **ROOTPATH/MyCompany/Database/Migrations** 中的任何迁移。这使得将迁移包含在您的可重用、模块化代码套件中变得简单。

命令行工具

CodeIgniter 附带了几个从命令行可用的 命令,以帮助您使用迁移。对于那些希望使用这些工具的人来说,这些工具使事情变得更容易。这些工具主要提供对 MigrationRunner 类中可用的相同方法的访问。

migrate

迁移具有所有可用迁移的数据库组

php spark migrate

您可以使用 (migrate) 以及以下选项

  • -g - 指定数据库组。如果指定,则只运行指定数据库组的迁移。如果没有指定,则运行所有迁移。

  • -n - 选择命名空间,否则将使用 App 命名空间。

  • --all - 将所有命名空间迁移到最新的迁移。

此示例将迁移 Acme\Blog 命名空间,并在测试数据库组上应用所有新的迁移。

适用于 Unix

php spark migrate -g test -n Acme\\Blog

适用于 Windows

php spark migrate -g test -n Acme\Blog

当使用 --all 选项时,它将扫描所有命名空间,尝试查找尚未执行的任何迁移。这些迁移将被收集并按创建日期分组排序。这将有助于最大程度地减少主应用程序与任何模块之间潜在的冲突。

回滚

将所有迁移回滚到空白状态,实际上是迁移 0。

php spark migrate:rollback

您可以使用 (回滚) 以及以下选项:

  • -b - 选择一个批次:自然数指定批次。

  • -f - 强制绕过确认问题,仅在生产环境中询问。

刷新

通过首先回滚所有迁移,然后迁移所有迁移来刷新数据库状态。

php spark migrate:refresh

您可以使用 (刷新) 以及以下选项:

  • -g - 指定数据库组。如果指定,则只运行指定数据库组的迁移。如果没有指定,则运行所有迁移。

  • -n - 选择命名空间,否则将使用 App 命名空间。

  • --all - 刷新所有命名空间。

  • -f - 强制绕过确认问题,仅在生产环境中询问。

状态

显示所有迁移的列表以及它们运行的日期和时间,或者如果它们尚未运行,则显示“–”。

php spark migrate:status

...

+----------------------+-------------------+-----------------------+---------+---------------------+-------+
| Namespace            | Version           | Filename              | Group   | Migrated On         | Batch |
+----------------------+-------------------+-----------------------+---------+---------------------+-------+
| App                  | 2022-04-06-234508 | CreateCiSessionsTable | default | 2022-04-06 18:45:14 | 2     |
| CodeIgniter\Settings | 2021-07-04-041948 | CreateSettingsTable   | default | 2022-04-06 01:23:08 | 1     |
| CodeIgniter\Settings | 2021-11-14-143905 | AddContextColumn      | default | 2022-04-06 01:23:08 | 1     |
+----------------------+-------------------+-----------------------+---------+---------------------+-------+

您可以使用 (状态) 以及以下选项:

  • -g - 指定数据库组。如果指定,则仅检查指定数据库组的迁移。如果没有指定,则会检查所有迁移。

创建:迁移

app/Database/Migrations 中创建迁移文件骨架。它会自动添加当前时间戳。它创建的类名是文件名的大写版本。

php spark make:migration <class> [options]

您可以使用 (make:migration) 以及以下选项:

  • --namespace - 设置根命名空间。默认值:APP_NAMESPACE

  • --suffix - 将组件标题追加到类名。

以下选项也可用于生成数据库会话的迁移文件

  • --session - 生成数据库会话的迁移文件。

  • --table - 用于数据库会话的表名。默认值:ci_sessions

  • --dbgroup - 用于数据库会话的数据库组。默认值:default

迁移偏好设置

以下是迁移的所有配置选项的表格,可在 app/Config/Migrations.php 中找到。

偏好设置

默认值

选项

描述

enabled

true

true / false

启用或禁用迁移。

table

migrations

用于存储架构版本号的表名。此表始终在默认数据库组 ($defaultGroup) 中创建。

timestampFormat

Y-m-d-His_

创建迁移时使用的日期时间格式。

类参考

class CodeIgniter\Database\MigrationRunner
findMigrations()
返回值:

迁移文件的数组

返回类型:

array

返回在 path 属性中找到的迁移文件名数组。

latest($group)
参数:
  • $group (mixed) – 数据库组名称,如果为空,将使用默认数据库组。

返回值:

true 成功,false 失败

返回类型:

bool

此方法会定位命名空间(或所有命名空间)的迁移,确定哪些迁移尚未运行,并按其版本顺序(命名空间交织)运行它们。

regress($targetBatch, $group)
参数:
  • $targetBatch (int) – 要回滚到的上一个批次;1+ 指定批次,0 回滚所有,负数表示相对批次(例如,-3 表示“三个批次前”)

  • $group (?string) – 数据库组名称,如果为空,将使用默认数据库组。

返回值:

true 成功,false 失败或未找到迁移

返回类型:

bool

Regress 可用于将更改回滚到上一个状态,一次一个批次。

<?php

$migration->regress(5);
$migration->regress(-1);
force($path, $namespace, $group)
参数:
  • $path (mixed) – 有效迁移文件的路径。

  • $namespace (mixed) – 提供的迁移的命名空间。

  • $group (mixed) – 数据库组名称,如果为空,将使用默认数据库组。

返回值:

true 成功,false 失败

返回类型:

bool

这会强制单个文件迁移,无论顺序或批次如何。方法 up()down() 是根据它是否已迁移来检测的。

注意

此方法仅推荐用于测试,可能会导致数据一致性问题。

setNamespace($namespace)
参数:
  • $namespace (string|null) – 应用程序命名空间。 null 是所有命名空间。

返回值:

当前 MigrationRunner 实例

返回类型:

CodeIgniter\Database\MigrationRunner

设置库应查找迁移文件的命名空间。

<?php

$migration->setNamespace($namespace)->latest();

注意

如果设置 null,它将在所有命名空间中查找迁移文件。

setGroup($group)
参数:
  • $group (string) – 数据库组名称。

返回值:

当前 MigrationRunner 实例

返回类型:

CodeIgniter\Database\MigrationRunner

设置库应查找迁移文件的组。

<?php

$migration->setGroup($group)->latest();