簡體   English   中英

如何在測試 laravel 中更改遷移中的枚舉類型列

[英]how to alter enum type column in migration in testing laravel

假設我有一個在生產環境中運行的代碼,因此,我無法更改相同的遷移文件以添加新列,如下所示

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我運行我的測試

請注意,首先數據庫將被遷移,並且由於該測試方法沒有開始

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 遷移機制的內置 function change ,如下所示:

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

請參閱: Laravel 遷移:修改列

我已經搜索並找到了這個解決方案,希望有用。

我的問題是數據庫的行為和對鍵的支持,當您使用 laravel 的遷移功能來更改enum類型時,您必須首先將doctrine/dbal package 添加到您的項目中

 composer require doctrine/dbal

then you must add enum type to doctrine because laravel is using the package to manipulate tables column and this laravel did not add enum type to the doctrine by default so __construct method in your altering migration is needed like below

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 項目站點上為ENUM類型提供的解決方案之一,它提供了兩種解決方案,第一個是Mapping to varchars ,第二個是Defining a custom type for enum

如果上述解決方案對您不起作用,那么您可以在doctrine 項目的站點中閱讀有關此問題的更多信息以及如何解決它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM