通过迁移更改表结构而不丢失数据?

Posted

技术标签:

【中文标题】通过迁移更改表结构而不丢失数据?【英文标题】:Change tables structures with migration without losing data? 【发布时间】:2017-03-03 17:19:45 【问题描述】:

我已经阅读了几个关于此的主题,但仍然不是我的问题。 所以在users 表中我有一个名为role 的列,它是枚举类型并且有两个可用值:1 和2。我将2 设置为默认值。例如,现在我想将其更改为 1。我创建了一个新迁移,运行 php artisan migrate 并遇到此错误:

[Illuminate\DatabaseQueryException]                                           

SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'role' (SQL: alter table `u  
  sers` add `role` enum('1', '2') not null default '1')                                                     
[PDOException]                                                             
  SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'role' 

这是我的 CreateUsersTable 迁移文件中的代码:

$table->enum('role', ['1', '2'])->default('2');

我在新的 UpdateUsersTable 迁移文件中做了同样的事情:

$table->enum('role', ['1', '2'])->default('1');

顺便说一句,我不能使用php artisan migrate:refresh,因为它会删除我的所有数据。我哪里做错了?

【问题讨论】:

【参考方案1】:
$table->enum('role', ['1', '2'])->default('1')->change();

【讨论】:

试过这个,它需要我安装教义/dbal。 但安装后提示“请求未知数据库类型枚举,Doctrine\DBAL\Platforms\mysql57Platform 可能不支持。” 是的,我在回答时错过了它。 laravel 中enum 类型有问题。看看这个答案***.com/a/40176304/5130217。可能更正确。 我把事情搞砸了。你知道如何卸载学说/dbal吗?我试过 sudo apt-get remove php-doctrine-dbal 但没有结果。可能是包名错误。 如果它是用 composer 安装的,你需要运行composer remove doctrine/dbal 来删除它【参考方案2】:
<?php

use Illuminate\Support\Facades\DB;
use Illuminate\Database\Migrations\Migration;

class UpdateUsersTable extends Migration

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        DB::statement('ALTER TABLE `users` MODIFY `role` DEFAULT 1;');
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        DB::statement('ALTER TABLE `users` MODIFY `role` DEFAULT 2;');
    

改编自this answer to another question

【讨论】:

@DuongNguyen ALTER TABLE users CHANGE COLUMN role role ENUM('1', '2') NOT NULL DEFAULT '1' ;【参考方案3】:

为此,您必须将-&gt;nullable()-&gt;default() 添加到您添加到迁移文件的每个字段中。

【讨论】:

【参考方案4】:

    创建一个新的迁移文件

    php artisan make:migration add_role_to_users_table --table=users
    

    打开创建的迁移文件(database\migrations\2021_12_01_050851-add_role_tables.php)并添加以下代码。

     <?php
     use Illuminate\Database\Migrations\Migration;
     use Illuminate\Database\Schema\Blueprint;
     use Illuminate\Support\Facades\Schema;
    
     class AddRoleToUsers extends Migration
     
         /**
          * Run the migrations.
          *
          * @return void
          */
         public function up()
         
             Schema::table('users', function (Blueprint $table) 
                 $table->enum('role', ['1', '2'])->default('1')->comment('1 - admin, 2 - normal'); //added
             );
         
    
         /**
          * Reverse the migrations.
          *
          * @return void
          */
         public function down()
         
             Schema::table('users', function (Blueprint $table) 
                 $table->dropColumn('role'); //added
             );
         
     
     ?>
    

    现在迁移刷新

    php artisan migrate:refresh --path=/database/migrations/2021_12_01_050851-add_role_tables.php
    

【讨论】:

以上是关于通过迁移更改表结构而不丢失数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何从表字段迁移 Hibernate @Audited 信息?

原创关于表结构更改的大量数据的迁移方案

原创关于表结构更改的大量数据的迁移方案

mysql结构复制从master到slave,slave数据完整

ef codeFirst 修改表结构 增加字段等 EF code first需要重新生成库导致数据丢失的问题.

PHPMYADMIN中的laravel更改表而无需迁移