phpixie/migrate

PHPixie 迁移组件

3.7.2 2021-05-12 18:42 UTC

This package is auto-updated.

Last update: 2024-09-13 02:08:23 UTC


README

PHPixie 迁移库

Author Source Code Software License

PHPixie Migrate 允许您对数据库模式进行版本控制,并以一致的方式应用更新。它还允许您定义一些要插入数据库的数据,这在编写测试或演示代码时非常有用。

配置

让我们看看默认配置在 assets/config/migrate.php

return array(
    // migration configs
    'migrations' => array(
        'default' => array(

            // database connection name
            'connection' => 'default',

            // migration files path, relative to /assets/migrate/
            'path'       => 'migrations',

            // optional:

            // name of the table to keep version data it
            'migrationTable' => '__migrate',

            // name of the version field in the migration table
            'lastMigrationField' => 'lastMigration'
        )
    ),

    // seed data configs (we'll cover it later)
    'seeds' => array(
        'default' => array(

            // database connection name
            'connection' => 'default',

            // seed files path, relative to /assets/migrate
            'path' => 'seeds'
        )
    )
);

您可能不需要在这里更改任何内容,除非您正在处理多个数据库或不同的种子数据集。

创建和销毁数据库

您现在可以使用命令行创建和销毁数据库。这是通过使用 framework:database 命令来完成的

framework:database ACTION [ CONFIG ]
Create or drop a database

Arguments:
ACTION    Either 'create' or 'drop'
CONFIG    Migration configuration name, defaults to 'default'

例如,运行 conole framework:database create 将创建一个数据库。

迁移

首先让我们简要介绍一下。迁移允许您将数据库模式修改保留在代码中,这比共享数据库转储或手动在生产数据库上应用更改要方便得多。它们以简单的方式工作:在数据库中创建一个特殊的表,该表只有一行一列,并保存最后一个应用的迁移名称。当执行迁移时,所有名称“大于”当前迁移名称的迁移都将按照 natsort() 顺序应用。例如,如果我们有文件 1.sql、2.sql,...22.sql,并且最新执行的迁移是 13.sql,那么14和22之间的所有迁移都将执行,并将最后一个迁移字段设置为22。迁移可以编写为 .sql 和 .php 格式。

SQL 迁移

这些非常简单。它只是一个带有 -- statement 分隔符的 SQL 文件。

CREATE TABLE fairies(
    id int NOT NULL,
    name VARCHAR(255)
);

-- statement

CREATE TABLE flowers(
    id int NOT NULL,
    name VARCHAR(255)
);

PHP 迁移

这些只是 PHP 文件,同时也允许您执行 SQL 命令,并提供对数据库组件的访问。

$this->execute("CREATE TABLE fairies(
    id int NOT NULL,
    name VARCHAR(255)
)");

$this->message("Output some message to the console");

// Usual Database queries
$this->connection()->updateQuery()
    ->table('users')
    ->set(['role' => 'user'])
    ->execute();

PHP 迁移比 SQL 迁移提供更多的灵活性,但 SQL 迁移文件也可以直接在数据库上执行,甚至不需要使用 Migrate 组件。

强烈建议在迁移名称中添加一些简短的描述,并且由于我们正在使用 natsort() 顺序,您可以在例如下划线之后安全地写入任何您喜欢的注释:33_fairies_table.sql

您还可以在迁移目录中使用子文件夹,这对于您有很多文件的情况非常有帮助。在这种情况下,排序将应用于整个子路径,而不仅仅是文件名。例如,您可以将文件组织如下:/2016/03/22/fairies_table.sql

要执行迁移,请使用 framework:migrate 命令

framework:migrate [ CONFIG ]
Run migrations on the database

Arguments:
CONFIG    Migration configuration name, defaults to 'default'

我们还需要回答一些问题。

为什么没有回滚迁移?

如果您从数据库本身的视角来看,没有模式回滚这回事。回滚只是应用另一个逆转之前更改的迁移。在许多情况下,回滚甚至是不可能的,例如,如果您回滚表删除,回滚可能会重新创建表结构,但不会将数据放回其中。

为什么更改是用原始 SQL 编写的,而不是使用一些通用方法,如 createTable 等?

通用方法的难题在于,它们经常忽略数据库之间的细微差异,并做出过多的假设。此外,更新后,这种通用库可能会以略微不同的方式创建表,而几个月前已经应用了迁移的生产数据库将处于与最近才应用了相同迁移的新数据库不同的状态。此外,已经存在许多用于创建和转换数据库模式的工具,因此没有必要在迁移库中重复这种功能。

种子

种子是一组可以用来填充数据库的数据。这可以是默认用户、项目类别等。它们还可以用来为某些功能测试准备应用程序。每个种子文件包含单个表的数据,其名称必须与该表的名称匹配。这些文件可以是.json.php,例如:

// /assets/migrate/seeds/fairies.php

<?php

return array(
    array(
        'id'   => 1,
        'name' => 'Pixie'
    ),
    array(
        'id'   => 2,
        'name' => 'Trixie'
    ),
);

或者

// /assets/migrate/seeds/flowers.json

[
    {
        "id": 1,
        "name": "daisy"
    },
    {
        "id": 2,
        "name": "Rose"
    },
]

当使用.php文件时,您还可以访问数据库组件

// /assets/migrate/seeds/fairies.php

<?php
$this->connection()->insertQuery()
    ->data([
        'id'   => 1,
        'name' => 'Pixie'
     ])
     ->execute();

要插入种子数据,请使用framework:seed命令

framework:seed [ --truncate ] [ CONFIG ]
Seed the database with data

Options:
truncate    Truncate the tables before inserting the data.

Arguments:
CONFIG    Seed configuration name, defaults to 'default'

如果某些要播种的表已经包含一些数据,这将导致错误。在插入数据之前清除表,请使用--truncate标志。

您可以通过将它们添加到/assets/config/migrate.php配置文件中,为同一个数据库连接在单独的目录中创建多个种子配置文件。

不使用框架

与其他PHPixie组件一样,您可以在不使用框架的情况下使用Migrate。例如,像这样:

$slice = new \PHPixie\Slice();
$database = new \PHPixie\Database($slice->arrayData(array(
    'default' => array(
        'database' => 'phpixie',
        'user'     => 'phpixie',
        'password' => 'phpixie',
        'adapter'  => 'mysql', // one of: mysql, pgsql, sqlite
        'driver'   => 'pdo'
    )
)));

$filesystem = new \PHPixie\Filesystem();
$migrate = new \PHPixie\Migrate(
    $filesystem->root(__DIR__.'/assets/migrate'),
    $database,
    $slice->arrayData(array(
    'migrations' => array(
        'default' => array(
            'connection' => 'default',
            'path'       => 'migrations',
        )
    ),
    'seeds' => array(
        'default' => array(
            'connection' => 'default',
            'path' => 'seeds'
        )
    )
)));

$cli = new \PHPixie\CLI();
$console = new \PHPixie\Console($slice, $cli, $migrate->consoleCommands());
$console->runCommand();

在这种情况下,控制台命令将是runseeddatabase,没有framework前缀。