18.ThinkPHP 擴展庫:數據庫遷移工具


數據庫遷移工具是干嘛的?

我們都知道我們寫的代碼可以用git或者svn進行代碼的版本控制,那么數據庫有沒有版本控制的呢?答案是有的。數據庫遷移工具就是用來干這個的

think-migration簡介

這是Thinkphp 提供擴展用戶數據庫的遷移和數據填充的擴展庫(也是數據庫遷移工具)

think-migration 安裝

通過 composer 安裝

composer require topthink/think-migration=2.0.*

注意事項,不支持修改文件配置目錄

image-20200531160108798

在命令行下運行查看幫助,可以看到新增的命令

php think 
 migrate
  migrate:create     Create a new migration
  migrate:rollback   Rollback the last or to a specific migration
  migrate:run        Migrate the database
  migrate:status     Show migration status
 optimize
  optimize:autoload  Optimizes PSR0 and PSR4 packages to be loaded wit
h classmaps too, good for production.
  optimize:config    Build config and common file cache.
  optimize:route     Build route cache.
  optimize:schema    Build database schema cache.
 seed
  seed:create        Create a new database seeder
  seed:run           Run database seeders

image-20200531160234558

think-migration 的使用

創建遷移類

注意:首字母必須為大寫

命令格式如下

php think migrate:create 遷移類名

migrate中的三個方法

up:在migrate:run時執行(前提是文件中不存在change方法)
down:在migrate:rollback時執行(前提是文件中不存在change方法)
change:migrate:run 和migrate:rollback時執行 (如果存在該方法 則不會去執行up 與down)

所以一般在創建完文件類過后刪除里面的change方法

一般情況下我一般將migrate文件中的change方法刪除,up方法專門放置新增和更新表的操作,down方法放置刪除表和刪除字段操作

change方法注意事項

遷移類里面的change()方法,主要是用來創建或者更新(修改)表,但是在change()方法內部創建或更新表時,必須使用表create()update()方法並且使用 change 方法后,updown 方法將被忽略

migrate 的命令

# 執行數據遷移操作,注意執行之前必須配好數據庫,也就是database.php
php think migrate:run

//回滾
php thin migrate:rollback  -t

使用遷移類在數據庫中創建一張表

1.配置數據庫

image-20200531165327168

2.創建數據遷移類

例:

php think migrate:create Test

image-20200531161254801

3.數據遷移類中寫入要創建表的字段和字段設置

對表的操作的幾個方法

更多的使用方法:https://book.cakephp.org/phinx/0/en/migrations.html

#注意:Table API完成以下操作是可逆的,並且將自動被逆轉
#migrate插件會自動id為每個表創建一個自動遞增的主鍵列,所以無需自己添加主鍵
table(創建表)
dropTable (刪除表)
renameTable(重命名表)
hasTable (判斷表是否存在)
addColumn(添加字段)
renameColumn(重命名字段)
addIndex(添加索引)
addForeignKey(添加外鍵)

表的array數組參數

Option Description
comment set a text comment on the table(表注釋)
row_format set the table row format(行格式)
engine define table engine (defaults to InnoDB)(表引擎)
collation define table collation (defaults to utf8_general_ci)(表的排序規則)
signed whether the primary key is signed (defaults to true)(是否將主鍵設置為無符號,默認為true,也就是有符號)

字段的array數組參數

For any column type:

對於任意的列,最常用

Option Description
limit set maximum length for strings, also hints column types in adapters (see note below)(設置字符串的最大長度)
length alias for limit(設置字符串的最大長度,跟limit一樣)
default set default value or action(設置默認值)
null allow NULL values, defaults to false (should not be used with primary keys!) (see note below)(允許“NULL”值,默認為false(不應該與主鍵一起使用!))
after specify the column that a new column should be placed after (only applies to MySQL)(指定新列應該放在后面的列)
comment set a text comment on the column(注釋)

For decimal columns:

對於小數

Option Description
precision combine with scale set to set decimal accuracy
scale combine with precision to set decimal accuracy
signed enable or disable the unsigned option (only applies to MySQL)

For enum and set columns:

用於' enum '和' set '列

Option Description
values Can be a comma separated list or an array of values

For integer and biginteger columns:

Option Description
identity enable or disable automatic incrementing
signed enable or disable the unsigned option (only applies to MySQL)

For timestamp columns:

Option Description
default set default value (use with CURRENT_TIMESTAMP)
update set an action to be triggered when the row is updated (use with CURRENT_TIMESTAMP) (only applies to MySQL)
timezone enable or disable the with time zone option for time and timestamp columns (only applies to Postgres)

up方法示例

例:

<?php

use think\migration\Migrator;
use think\migration\db\Column;

class Test extends Migrator
{
    public function up()
    {
        // 表名
        $table = $this->table('Test',array('engine'=>'MyISAM'));
        $table->addColumn('username', 'string',array('limit' => 15,'default'=>'','comment'=>'用戶名,登陸使用'))
            ->addColumn('password', 'string',array('limit' => 32,'default'=>md5('123456'),'comment'=>'用戶密碼'))
            ->addColumn('login_status', 'boolean',array('limit' => 1,'default'=>0,'comment'=>'登陸狀態'))
            ->addColumn('login_code', 'string',array('limit' => 32,'default'=>0,'comment'=>'排他性登陸標識'))
            ->addColumn('last_login_ip', 'integer',array('limit' => 11,'default'=>0,'comment'=>'最后登錄IP'))
            ->addColumn('last_login_time', 'datetime',array('default'=>0,'comment'=>'最后登錄時間'))
            ->addColumn('is_delete', 'boolean',array('limit' => 1,'default'=>0,'comment'=>'刪除狀態,1已刪除'))
            ->addIndex(array('username'), array('unique' => true))
            ->create();
    }
}

image-20200531175501866

4.執行數據遷移

執行命令

php think migrate:run

image-20200531175610045

遷移成功后會生成兩個表一個是你寫入up方法生成的表,一個是migrations表,migrations表用於記錄本次操作的記錄

更新表字段數據

1.創建修改的的遷移類

php think migrate:create ChangeTest

2.將需要更新的內容寫到 change 方法中

 #使用up方法也可以
 public function change()
    {
        //表名
        $table = $this->table('test');
        //修改字段類型,注意修改用的是save方法
        $table->changeColumn('password', 'char', ['limit' => 50])
            ->addColumn('test_Cloumn', 'varchar', array('limit' => 32, 'default' => ''))
            ->save();

    }

3.執行數據遷移操作

自動會執行最近一次創建的數據遷移了

php think migrate:run

image-20200531181047800

而且這時候你打開migrations會發現多了一條操作記錄

image-20200531181158219

執行回滾

執行 migrate:rollback 功能會調用down 方法

1.創建回退數據遷移類

php think migrate:create Back

2.寫down()方法

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

3.執行回退

#默認執行最新的數據遷移類的down里面的方法
php think migrate:rollback

#php think migrate:rollback -t 回滾到指定的版本
例:php think migrate:rollback -t 20200531080828

image-20200531184038578

seed數據填充

1.創建seed

$ php think seed:create AddTest

image-20200531185505681

2.編輯seed文件的run()方法

public function run()
    {
        $data = [
            [
                'username' => 'testUesr1',
                'password' => '11111',
                'login_status' => 0,
            ],
            [
                'username' => 'testUesr2',
                'password' => '11111',
                'login_status' => 0,
            ],
        ];
        $this->table('test2')->insert($data)->save();

    }
}

3. 開始進行數據庫填充

$ php think seed:run

結果如下

image-20200531190205257

可指定一個或多個 seed

$ php think seed:run -s Third
$ php think seed:run -s Third -s member

使用假數據生成器

參考 fzaninotto/faker:https://packagist.org/packages/fzaninotto/faker

安裝 faker 類庫

$ composer require fzaninotto/faker

使用 faker 生成數據

public function run()
{
    $faker = Faker\Factory::create('zh_CN');//選擇中文庫
    $data = [];
    for ($i = 0; $i < 100; $i++) {
        $data[] = [
            'member_id' => $faker->randomDigit,
            'thirdid' => $faker->randomDigit,
            'platform' => $faker->word,
            'openid' => sha1($faker->password),
            'content' => $faker->realText(50),
        ];
    }
    $this->table('third')->insert($data)->save();
}
結果如下:

C6Aad5vo2x (assets/C6Aad5vo2x (1).png)

insert方式數據填充

除了上面的seed數據填充方式,就是insert()方式,這種方式一般在數據直接將要插入的數據放在數據遷移類中

如:

$table->insert([
    'uid'=>1,
    'group_id'=>1
]);
$table->save();

php 7.4.5 執行創建遷移類報錯的問題

http://www.thinkphp.cn/bug/5056.html

執行 : 
php think migrate:create Admin
報錯:
[think\exception\ErrorException]                                               
  implode(): Passing glue string after array is deprecated. Swap the parameters  

解決辦法

找到下面路徑的文件

vendor/topthink/think-migration/phinx/src/Phinx/Util/Util.php

搜索implode

image-20201022170341237

implode($arr, '_') 這個修改為 implode('_',$arr)

image-20201022170524897

再次執行

php think migrate:create Admin

就沒問題了

實際使用Demo

安裝

composer require topthink/think-migration=2.0.*

創建遷移類

注意:首字母必須為大寫

命令格式如下

php think migrate:create 遷移類名

例:

php think migrate:create Admin
php think migrate:create User

生成的文件位置如

image-20201022171817601

寫入管理員表和用戶表的字段信息和數據

找到剛才用命令生成的兩個遷移類文件,在change方法中寫入你要生成的字段信息和數據

20201022090610_admin.php

<?php

use think\migration\Migrator;
use think\migration\db\Column;

class Admin extends Migrator
{
    public function change()
    {
        $table = $this->table('admin');
        $table->addColumn('username', 'string', ['limit'=>50, 'default'=>'', 'comment'=>'登陸賬號']);
        $table->addColumn('nickname', 'string', ['limit'=>50, 'default'=>'', 'comment'=>'昵稱']);
        $table->addColumn('mobile', 'string', ['limit'=>11, 'default'=>'', 'comment'=>'手機號']);
        $table->addColumn('password', 'string', ['limit'=>255, 'default'=>'']);
        $table->addColumn('avatar', 'string', ['limit'=>255, 'default'=>'', 'comment'=>'頭像']);
        $table->addColumn('register_ip', 'string', ['limit'=>20, 'default'=>'', 'comment'=>'IP']);
        $table->addColumn('login_time', 'integer', ['default'=>0, 'comment'=>'最后登陸時間']);
        $table->addColumn('login_ip', 'string', ['default'=>20, 'comment'=>'最后登陸IP']);
        $table->addColumn('login_num', 'integer', ['limit'=>4, 'default'=>0, 'comment'=>'登陸次數']);
        $table->addColumn('status', 'boolean', ['default'=>1, 'comment'=>'用戶狀態(0:禁用,1:開啟)']);
        $table->addColumn('register_time', 'integer', ['default'=>0]);
        $table->addColumn('update_time', 'integer', ['default'=>0]);

        $table->insert([
            'username'=>'root',
            'nickname'=>'root',
            'mobile'=>'13000000000',
            'password'=>md5('123456'),
            'avatar'=>'/uploads/product/2018-11-08/5be3de5c38d63.png',
            'register_ip'=>'127.0.0.1',
            'login_ip'=>'0.0.0.0',
            'register_time'=>$_SERVER['REQUEST_TIME']
        ]);

        $table->save();
    }
}

20201022090859_user.php

<?php

use think\migration\Migrator;
use think\migration\db\Column;

class User extends Migrator
{
    public function change()
    {
        $table = $this->table('user');
        $table->addColumn('username', 'string', ['limit'=>50, 'default'=>'', 'comment'=>'登陸賬號']);
        $table->addColumn('nickname', 'string', ['limit'=>50, 'default'=>'', 'comment'=>'昵稱']);
        $table->addColumn('mobile', 'string', ['limit'=>11, 'default'=>'', 'comment'=>'手機號']);
        $table->addColumn('password', 'string', ['limit'=>255, 'default'=>'']);
        $table->addColumn('avatar', 'string', ['limit'=>255, 'default'=>'', 'comment'=>'頭像']);
        $table->addColumn('register_ip', 'string', ['limit'=>20, 'default'=>'', 'comment'=>'IP']);
        $table->addColumn('login_time', 'integer', ['default'=>0, 'comment'=>'最后登陸時間']);
        $table->addColumn('login_ip', 'string', ['default'=>20, 'comment'=>'最后登陸IP']);
        $table->addColumn('login_num', 'integer', ['limit'=>4, 'default'=>0, 'comment'=>'登陸次數']);
        $table->addColumn('status', 'boolean', ['default'=>1, 'comment'=>'用戶狀態(0:禁用,1:開啟)']);
        $table->addColumn('register_time', 'integer', ['default'=>0]);
        $table->addColumn('update_time', 'integer', ['default'=>0]);

        $table->insert([
            'username'=>'張三',
            'nickname'=>'張三',
            'mobile'=>'13000000000',
            'password'=>md5('123456'),
            'avatar'=>'/uploads/product/2018-11-08/5be3de5c38d63.png',
            'register_ip'=>'127.0.0.1',
            'login_ip'=>'0.0.0.0',
            'register_time'=>$_SERVER['REQUEST_TIME']
        ]);

        $table->save();
    }
}

配置好數據庫連接

image-20201022172213750

執行數據遷移

php think migrate:run

連接數據庫,查看效果

image-20201022172613525


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM