当前位置: 首页 > news >正文

PHP单独使用phinx使用数据库迁移

可以独立使用的迁移包对比后,感觉phinx更接近PHP的使用习惯。

为什么要单独用?

因为我不想数据库的迁移文件依赖于某种框架。本来是可以在框架里直接安装这个包的,但是发现这个包依赖cakephp,而cakephp的函数与thinkphp的env()函数冲突。

官方文档:Phinx Documentation - 0.16

安装

新建个空目录,然后在这个目录执行:

composer require robmorgan/phinx

安装好后,在目录vendor\bin中能找到文件:phinx.bat。

建议:将vendor\bin的路径加入到系统变量path中,就可以直接用这个命令了。

命令

查看可用命令列表

phinx

查看可用命令的帮助,如:

phinx init --help

初始配置文件

phinx init E:\a\b

假设项目目录为:E:\a\b\。在目录下创建配置文件phinx.php和phinx.yml,建议使用.php的文件(因为不用额外装包),删除掉phinx.yml。项目目录不是phinx的安装目录。

文件内容如下:

<?phpreturn
['paths' => ['migrations' => '%%PHINX_CONFIG_DIR%%/db/migrations','seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds'],'environments' => ['default_migration_table' => 'phinxlog','default_environment' => 'development','production' => ['adapter' => 'mysql','host' => 'localhost','name' => 'production_db','user' => 'root','pass' => '','port' => '3306','charset' => 'utf8',],'development' => ['adapter' => 'mysql','host' => 'localhost','name' => 'development_db','user' => 'root','pass' => '','port' => '3306','charset' => 'utf8',],'testing' => ['adapter' => 'mysql','host' => 'localhost','name' => 'testing_db','user' => 'root','pass' => '','port' => '3306','charset' => 'utf8',]],'version_order' => 'creation'
];

[path] 节可以指定迁移文件和种子文件所在的目录,可以指定为数组,如:

'paths' => [

        'migrations' => [

            '%%PHINX_CONFIG_DIR%%/db/migrations',

            'd:/a/b'

        ],

        'seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds'

    ],

%%PHINX_CONFIG_DIR%% 变量是phinx的内置变量,是配置文件所在的目录。

[environments] 节为数据库环境配置:

default_migration_table:指定保存迁移记录的表名,执行迁移时会生成以这个为表名的表,保存每次执行的记录。

default_environment:默认使用的环境,development为开发环境,将development节下的数据库配置好。

创建迁移文件

phinx create SystemDict --path=E:\a\b\db\migrations -c E:\a\b\phinx.php

phinx create 表名 --path=存放迁移文件的目录 -c 配置文件路径(即执行init时创建的文件)

将会在目录中创建一个迁移文件,名称类似于:20250830084537_system_dict.php。

如果用的是IDE打开文件,可以看到AbstractMigration是标红的,这是因为phinx包不在项目目录中。可以配置下IDE的PHP包含路径:D:\soft\php\tools\vendor。

这是vscode的配置,我这里用的是Trae。

执行迁移

phinx migrate -c E:\a\b\phinx.php

将命令行的当前目录切换为:E:\a\b\,可直接执行phinx migrate,不需要指定配置文件。

可以看到执行成功了,但是由于迁移文件是个空的,所以数据库中没有任何变化,只是多了一个表:phinxlog。这就是配置文件中指定的表名,非必要时不需要特意去改。表里有了一条记录:

现在到迁移文件中添加表的定义:

<?phpdeclare(strict_types=1);use Phinx\Migration\AbstractMigration;final class SystemDict extends AbstractMigration
{/*** Change Method.** Write your reversible migrations using this method.** More information on writing migrations is available here:* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method** Remember to call "create()" or "update()" and NOT "save()" when working* with the Table class.*/public function change(): void{// 定义表$table = $this->table('__table_prefix__system_dict', ['id' => false, 'primary_key' => ['id'], 'comment' => '系统字典']);// 定义表字段和索引$table->addColumn('id', 'biginteger', ['limit' => 20, 'null' => false, 'signed' => false, 'identity' => true, 'comment' => '主键'])->addColumn('create_time', 'datetime', ['comment' => '创建时间'])->addColumn('update_time', 'datetime', ['comment' => '更新时间'])->addColumn('code', 'string', ['limit' => 100, 'comment' => '字典编码'])->addColumn('title', 'string', ['comment' => '字典标题,显示名'])->addIndex('code', ['unique' => true, 'name' => 'idx_dict_code'])->create();}
}

现在再去执行迁移命令,发现什么都没有变化。这是因为这个文件前一次已经执行过了,在phinxlog表中已经有了记录。要再次执行这个文件,需要先回滚掉前一次执行的记录。

为什么要在表定义设置 id=false?

phinx默认情况下会建一个名为id的int类型的主键字段,但有时候我们不想用int或是不想用id作为主键字段名。这时我们就要自已定义字段了。

回滚

phinx rollback -c E:\a\b\phinx.php

加了代码后执行,会得到一个错误:

这是因为之前执行时没有建表,现在回滚导致找不到表。先将代码中那表的代码注释掉,再执行回滚,回滚后再放开注释掉的代码。当然也可以手动删除迁移表中的记录,但不建议这么干。

每次执行回滚,只会回滚最后一次执行的迁移。如果想一次回滚多个记录,可以用-t参数指定回滚到的版本,具体可以查看回滚的帮助。

phinx rollback -c E:\a\b\phinx.php  -t 20250830084537 # 是回滚到这个版本(这个不会回滚,只回滚这个版本之后的所有版本)

phinx rollback -c E:\a\b\phinx.php  -t 0 # -t 参数指定为0时,将回滚所有版本!!

回滚后再执行下迁移,可以看到表建好了:

查看回滚的帮助

phinx rollback --help

支持的字段类型

以下是各种数据库都支持的类型

binary
boolean
char
date
datetime
decimal
float
double
smallinteger
integer
biginteger
string
text
time
timestamp
uuid

如果想用特殊类型,参考:Writing Migrations - 0.16,为了通用性,不建议使用特殊的类型。

问题

目前还没有发现如何统一定义表前缀。

http://www.dtcms.com/a/358915.html

相关文章:

  • 全栈开源,高效赋能——启英泰伦新官网升级上线!
  • 快速学习和掌握Jackson 、Gson、Fastjson
  • React Native基本用法
  • 大语言模型生成的“超龄劳动者权益保障制度系统化完善建议(修订版)”
  • 下一波红利:用 #AI编程 闯入小游戏赛道,#看广告变现 模式正在崛起!
  • I2C的类比水池和大海
  • 【前端教程】DOM 操作入门专栏:从基础到实战
  • JS之刷刷
  • Langflow核心技术学习笔记(新)
  • LangChain.js 实战与原理:用 LCEL 构建可维护的 RAG / Agent 系统(含 4 套 30+ 行代码)
  • 揭开智能体架构面纱:90% 属软件工程,10% 为 AI 技术
  • Python数据分析:在Python中,reindex和set_index以及reset_index最本质的区别是什么?
  • B树与B+树的原理区别应用
  • Python 的 argparse 模块中,add_argument 方法的 nargs 参数
  • Ubuntu系统下交叉编译Android的X264库
  • hello算法笔记 01
  • Jedis、Lettuce、Redisson 技术选型对比
  • 下载 | Win11 23H2正式版最新原版ISO系统映像 (22631.5840、多合一版本)-修复系统问题
  • LangGraph 深度解析(二):掌握 LangGraph 函数式 API 的状态化 AI 工作流
  • openEuler2403安装部署Redis8
  • JavaScript之性能优化
  • HiFi-GAN模型代码分析
  • txt2las批量测井txt文件转las
  • 【C++】类和对象3
  • 【学Python自动化】 1. Python 安装与配置完全指南 (Windows)
  • 微论-突触的作用赋能思考(可能是下一代人工智能架构的启发式理论)
  • fastdds qos:LifespanQosPolicy
  • 2025年- H101-Lc209--1979.找出数组的最大公约数(gcd最大公约数)--Java版
  • STM32G474 IAP 双bank升级的坑
  • git的三种分区与分支的关系