如何在测试中更改迁移中的枚举类型列 laravel

how to alter enum type column in migration in testing laravel

假设我有一个在生产环境中 运行ning 的代码,因此,我无法更改相同的迁移文件来添加新列,如下所示

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name')->nullable();
            $table->string('email')->unique();
            $table->string('token_key')->unique()->nullable();
            $table->enum('type', ['avatar', 'image', 'video'])->comment(implode(', ', ['avatar', 'image', 'video']));
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

并且在第一次发布之后,我想从名为 type 可接受值的列中删除 avatar 值,因此我添加了一个新的迁移文件来添加我的新列,如下所示

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class ChangeEnumOnUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        $sql = sprintf(
            "ALTER TABLE %s CHANGE `%s` `%s` ENUM('%s') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '%s'",
            'users',
            'type',
            'type',
            implode('\',\'', ['image', 'video']),
            implode(',', ['image', 'video'])
        );
        DB::statement($sql);
    }
}

并使用 vendor/bin/phpunit 我 运行 我的测试

please attention that first of all database will get migrated and because of that test method does not getting started

SQLite 抛出如下错误。

SQLite 异常就像

PDOException: SQLSTATE[HY000]: General error: 1 near "CHANGE": syntax error

Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 near "CHANGE": syntax error (SQL: ALTER TABLE users CHANGE `type` `type` ENUM('image','video') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'image,video')

您不能使用 DB::statement 和您的 sprintf 来修改您的字段。

所以你可以像这样使用Laravel迁移机制的内置函数change:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change(); // update the field by increasing the max allowed characters
});

参见:Laravel Migration: Modifying Columns

我已经搜索并找到了这个解决方案,希望有用。

我的问题是数据库的行为和键的支持,当您使用 laravel 的迁移功能来更改 enum 类型时,您必须首先将 doctrine/dbal 包添加到您的项目

 composer require doctrine/dbal

那么您必须将 enum 类型添加到学说中,因为 laravel 正在使用包来操作表列,而此 laravel 并未将 enum 类型添加到学说中默认情况下,因此需要 __construct 更改迁移中的方法,如下所示

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\StringType;

public function __construct()
{
    if (! Type::hasType('enum')) {
        Type::addType('enum', StringType::class);
    }
    DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
}

然后您可以像下面这样更改 enum

$table->enum('type', ['avatar', 'video'])
      ->comment(implode(', ', ['avatar', 'video']))
      ->change();

并且知道在测试时更改枚举类型字段没有问题。

注意: 此解决方案是 doctrine project's site 上为 ENUM 类型提供的解决方案之一,它提供了两个解决方案,第一个是 Mapping to varchars,第二个是 Defining a custom type for enum

如果上述解决方案对您不起作用,那么您可以在 doctrine project's site 自己

中阅读有关此问题以及如何解决它 ]