数据库迁移(Database Migrations)
在开发过程中,我们通常需要更新生产环境中的更改。其中一些更改可能是数据库修改,如新字段、新表、删除索引等。
生成迁移时,将创建一组类来描述数据库在那个特定时刻的结构。这些类可用于同步远程数据库上的架构结构,使数据库准备好使用应用程序实现的新更改。迁移使用普通 PHP 描述这些转换。
migrations提供了用于**管理迁移(生成,运行和回滚)**的脚本
phalcon3.*里没有单独的migrations
需要安装Phalcon 开发工具(Phalcon Developer Tools),文档安装说明
phalcon4以上可以直接composer,文档连接
composer require --dev phalcon/migrations
在控制台(或命令行)里输入phalcon migration --help得到以下提示
phalcon migration --help
Phalcon DevTools (3.4.14)
Help:
Generates/Run a Migration
Usage: Generate a Migration
migration generate
Usage: Run a Migration
migration run
Usage: List all available migrations
migration list
Arguments:
help Shows this help text
Options:
--action=s Generates a Migration [generate|run]
--config=s Configuration file
--migrations=s Migrations directory. Use comma separated string to specify multiple directories
--directory=s Directory where the project was created
--table=s Table to migrate. Table name or table prefix with asterisk. Default: all
--version=s Version to migrate
--descr=s Migration description (used for timestamp based migration)
--data=s Export data [always|oncreate] (Import data when run migration)
--exportDataFromTables=s Export data from specific tables, use comma separated string.
--force Forces to overwrite existing migrations
--ts-based Timestamp based migration version
--log-in-db Keep migrations log in the database table rather than in file
--dry Attempt requested operation without making changes to system (Generating only)
--verbose Output of debugging information during operation (Running only)
--no-auto-increment Disable auto increment (Generating only)
--help Shows this help [optional]
--action=s 生成迁移[generate|run]
--config=s 配置文件
--migration=s 迁移目录。使用逗号分隔的字符串指定多个目录
--directory=s 创建项目的目录
--table=s 要迁移的表。表名或带有星号的表前缀。默认值:all
--version=s 要迁移的版本
--descr=s 迁移描述(用于基于时间戳的迁移)
--data=s 导出数据[always|oncreate](运行迁移时导入数据)
--exportDataFromTables=s 从特定表中导出数据,使用逗号分隔的字符串。
--force 强制覆盖现有迁移
--ts-based 基于时间戳的迁移版本
--log-in-db 将迁移日志保存在数据库表中,而不是文件中
--dry 尝试在不更改系统的情况下请求的操作(仅用于生成)
--verbose 操作期间调试信息的输出(仅运行)
--no-auto-increment 禁用自动增量(仅生成)
--help 显示此帮助[可选]
注意事项
在没有任何参数的情况下运行此脚本将简单地将数据库中的每个对象(表和视图)转储到迁移类中。
每个迁移都有一个与之关联的版本标识符。版本号使我们能够确定迁移是比数据库的当前“版本”更新还是旧。版本还会在执行迁移时通知 Phalcon 运行顺序。
如果运行时报错:
phalcon migration generate
##节选部分运行结果
Phalcon DevTools (3.4.14)
Warning: Use of undefined constant APP_PATH - assumed 'APP_PATH' (this will throw an Error in a future version of PHP) in ***(项目config.php路径)
在config.php里增加 APP_PATH和BASE_PATH:
define('BASE_PATH', dirname(dirname(__DIR__)));
define('APP_PATH', BASE_PATH . '/app');
再次运行,可能会得到不能加载数据库:
Phalcon DevTools (3.4.14)
ERROR: Cannot load database configuration
检查文档,得到config.ini配置,配置连接:
[database]
adapter = Mysql
host = "127.0.0.1"
username = "root"
password = "***"
dbname = "***"
[phalcon]
controllersDir = "../app/controllers/"
modelsDir = "../app/models/"
viewsDir = "../app/views/"
baseUri = "/store/"
再次运行,在app目录下面出现了migration文件夹,命令行里提示,同时在文件夹下面生成了对应数据的文件,每个文件将已有的字段都列出来了:
Phalcon DevTools (3.4.14)
Success: Version 1.0.4 was successfully generated
生成迁移时,控制台上会显示说明,描述迁移的不同步骤以及这些语句的执行时间。最后,将生成迁移版本。
默认情况下,Phalcon 开发人员工具使用 app/migrations 目录来转储迁移文件。您可以通过在生成脚本上设置其中一个参数来更改位置。数据库中的每个表都有其各自的类,在引用其版本的目录下的单独文件中生成:
迁移类剖析(Migration Class Anatomy)
每个文件都包含一个扩展该类的唯一类。这些类通常有两个方法:up()和down() 。 执行迁移,同时回滚迁移。Phalcon\Mvc\Model\Migrationup()down()up()down()
up()还包含魔法。当它认识到将数据库中的实际表同步到给定的描述所需的更改时,魔术就出现了。morphTable()
<?php
use Phalcon\Db\Column as Column;
use Phalcon\Db\Index as Index;
use Phalcon\Db\Reference as Reference;
use Phalcon\Mvc\Model\Migration;
class ProductsMigration_100 extends Migration
{
public function up()
{
$this->morphTable(
"products",
[
"columns" => [
new Column(
"id",
[
"type" => Column::TYPE_INTEGER,
"size" => 10,
"unsigned" => true,
"notNull" => true,
"autoIncrement" => true,
"first" => true,
]
),
new Column(
"product_types_id",
[
"type" => Column::TYPE_INTEGER,
"size" => 10,
"unsigned" => true,
"notNull" => true,
"after" => "id",
]
),
new Column(
"name",
[
"type" => Column::TYPE_VARCHAR,
"size" => 70,
"notNull" => true,
"after" => "product_types_id",
]
),
new Column(
"price",
[
"type" => Column::TYPE_DECIMAL,
"size" => 16,
"scale" => 2,
"notNull" => true,
"after" => "name",
]
),
],
"indexes" => [
new Index(
"PRIMARY",
[
"id",
]
),
new Index(
"product_types_id",
[
"product_types_id",
],
),
],
"references" => [
new Reference(
"products_ibfk_1",
[
"referencedSchema" => "invo",
"referencedTable" => "product_types",
"columns" => ["product_types_id"],
"referencedColumns" => ["id"],
]
),
],
"options" => [
"TABLE_TYPE" => "BASE TABLE",
"ENGINE" => "InnoDB",
"TABLE_COLLATION" => "utf8_general_ci",
],
]
);
}
}
该类称为“ProductsMigration_100”。后缀 100 是指版本 1.0.0。 接收一个包含 4 个可能部分的关联数组:morphTable()
字段 | 描述 | 可选 |
---|---|---|
columns | 包含一组表列的数组 | 必选 |
indexes | 包含一组表列的数组 | 可选 |
references | 具有一组表引用(外键)的数组。 | 可选 |
options | 具有一组表创建选项的数组。这些选项通常与生成迁移的数据库系统相关。 | 可选 |
定义列(Defining Columns)
Phalcon\Db\Column 用于定义表列。它封装了各种与列相关的功能。它的构造函数接收列名和描述列的数组作为第一个参数。描述列时可以使用以下选项:
选项 | 描述 | 可选 |
---|---|---|
type | 列类型。必须是Phalcon_Db_Column常量(见下文) | 必选 |
size | 某些类型的列(如 VARCHAR 或 INTEGER)可能具有特定大小 | 可选 |
scale | 十进制或数字列可能有一个刻度来指定它必须存储多少小数 | 可选 |
unsigned | 整数列可以是有符号的,也可以是无符号的。此选项不适用于其他类型的列 | 可选 |
notNull | 列可以存储空值吗? | 可选 |
default | 定义列的默认值(只能是实际值,不能是 NOW() 等函数) | 可选 |
autoIncrement | 使用此属性列将自动填充自动递增整数。表中只有一列可以具有此属性。 | 可选 |
first | 列必须放置在列顺序中的第一个位置 | 可选 |
after | 列必须放置在列顺序中的第一个位置 | 可选 |
列必须放置在列顺序中的第一个位置
Phalcon\Db\Column::TYPE_INTEGER
Phalcon\Db\Column::TYPE_VARCHAR
Phalcon\Db\Column::TYPE_CHAR
Phalcon\Db\Column::TYPE_DATE
Phalcon\Db\Column::TYPE_DATETIME
Phalcon\Db\Column::TYPE_TIMESTAMP
Phalcon\Db\Column::TYPE_DECIMAL
Phalcon\Db\Column::TYPE_TEXT
Phalcon\Db\Column::TYPE_BOOLEAN
Phalcon\Db\Column::TYPE_FLOAT
Phalcon\Db\Column::TYPE_DOUBLE
Phalcon\Db\Column::TYPE_TINYBLOB
Phalcon\Db\Column::TYPE_BLOB
Phalcon\Db\Column::TYPE_MEDIUMBLOB
Phalcon\Db\Column::TYPE_LONGBLOB
Phalcon\Db\Column::TYPE_JSON
Phalcon\Db\Column::TYPE_JSONB
Phalcon\Db\Column::TYPE_BIGINTEGER
定义索引
Phalcon\Db\Index 定义表索引。索引只需要您为其定义名称及其列列表。请注意,如果任何索引的名称为 PRIMARY,Phalcon 将为该表创建一个主键索引;
定义关系
Phalcon\Db\Reference 定义表引用(也称为外键)。以下选项可用于定义引用:
参数 | 描述 | 可选 | 数据库 |
---|---|---|---|
referencedTable | 它是自动描述的。它引用引用的表的名称。 | No | All |
columns | 一个数组,其中包含表中具有引用的列的名称 | No | All |
referencedColumns | 具有引用表中列名称的数组 | No | All |
referencedSchema | 引用的表可能位于另一个架构或数据库上。此选项允许您定义它。 | No | All |
onDelete | 如果更新了外来记录,请对本地记录执行此操作。 | yes | MySQL PostgreSQL |
onUpdate | 如果更新了外来记录,请对本地记录执行此操作。 | No | MySQL PostgreSQL |
创建迁移类(Writing Migrations)
迁移不仅旨在“morph”表。迁移只是一个常规的 PHP 类,因此您不仅限于这些函数。例如,添加列后,您可以编写代码来为现有记录设置该列的值。有关各个方法的更多详细信息和示例,请查看数据库组件。
<?php
use Phalcon\Mvc\Model\Migration;
class ProductsMigration_100 extends Migration
{
public function up()
{
// ...
self::$_connection->insert(
"products",
[
"Malabar spinach",
14.50,
],
[
"name",
"price",
]
);
}
}
执行迁移(Running Migrations)
将生成的迁移上载到目标服务器上后,可以轻松运行它们;
根据数据库在迁移方面的过时程度,Phalcon 可能会在同一迁移过程中运行多个迁移版本。如果指定目标版本,Phalcon 将运行所需的迁移,直到达到指定的版本。