как изменить столбец типа перечисления в миграции при тестировании laravel - PullRequest
0 голосов
/ 01 августа 2020

при условии, что у меня есть код, который работает в производственной среде, и из-за этого я не могу изменить тот же файл миграции для добавления новых столбцов, как показано ниже

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');
    }
}

, и после первого выпуска я хотите удалить значение avatar из столбца с именем type допустимые значения, поэтому я добавляю новый файл миграции для добавления моего нового столбца, как показано ниже

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')

Ответы [ 2 ]

1 голос
/ 02 августа 2020

Вы не можете использовать DB::statement и sprintf для изменения своего поля.

Таким образом, вы можете использовать встроенную функцию change механизма миграции Laravel следующим образом:

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

См .: Laravel Миграция: изменение столбцов

0 голосов
/ 10 августа 2020

Я искал и нашел это решение, надеюсь, оно будет полезным.

Моя проблема заключалась в поведении базы данных и поддержке ключей, когда вы используете функции миграции laravel для изменения типа enum, который вы сначала необходимо добавить пакет doctrine/dbal в свой проект

 composer require doctrine/dbal

затем вы должны добавить тип enum к doctrine, потому что laravel использует пакет для управления столбцом таблиц, а этот laravel не добавьте тип enum к doctrine по умолчанию, поэтому метод __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();

и знайте, что нет проблем с изменением поля типа перечисления при тестировании.

ВНИМАНИЕ : это решение является одним из предлагаемых решений для типов ENUM на doctrine сайт проекта , и он предлагает два решения: первое - Mapping to varchars, второе - Defining a custom type for enum

Если вышеуказанное решение не сработало для вас, вы можете узнать больше о этот вопрос и как чтобы решить в doctrine на сайте проекта себе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...