php Laravel 5.1 请求的未知数据库类型枚举

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33140860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:24:01  来源:igfitidea点击:

Laravel 5.1 Unknown database type enum requested

phplaravellaravel-4laravel-5

提问by karthick

While running php artisan migrate, I got the following error

运行php artisan migrate 时,出现以下错误

[Doctrine\DBAL\DBALException]
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.

[Doctrine\DBAL\DBALException]
请求未知的数据库类型枚举,Doctrine\DBAL\Platforms\MySqlPlatform 可能不支持它。

How to resolve this issue.

如何解决这个问题。

Code:

代码:

public function up() {
    Schema::table('blogs', function (Blueprint $table) {
        $table->string('wordpress_id')->nullable();
        $table->string('google_blog_id')->nullable()->change();
    });
}

回答by Xeleon

It is a known issue as stated in Laravel 5.1 documentation.

这是 Laravel 5.1文档中所述的已知问题。

Note: Renaming columns in a table with a enumcolumnis not currently supported.

注意:当前不支持使用enum重命名表中的

It happens when you have a enumcolumn in your database table. Whether you are trying to rename another column, or change another column to nullable, this bug will appear. It's an issue with Doctrine\DBAL.

当您enum的数据库表中有列时会发生这种情况。无论您是尝试重命名另一列,还是将另一列更改为nullable,都会出现此错误。这是一个问题Doctrine\DBAL

An easy fixfor this is to just add this constructor method in your database migration file.

一个简单的解决方法是在你的数据库迁移文件中添加这个构造函数方法。

public function __construct()
{
    DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
}

This will map all the ENUMcolumns to VARCHAR(), and the column will accept any string.

这会将所有ENUM列映射到VARCHAR(),并且该列将接受任何字符串。

This worked for me on Laravel 5.1 and Laravel 5.3. I hope this bug can be fixed soon.

这在 Laravel 5.1 和 Laravel 5.3 上对我有用。我希望这个错误可以尽快修复。

Credit to @Gmatkowski's answer athttps://stackoverflow.com/a/32860409/1193201

感谢@Gmatkowski 在https://stackoverflow.com/a/32860409/1193201 上的回答

回答by Adrenaxus

The official Laravel 5.1 documentationstates:

Laravel 5.1 官方文档指出:

Note: Renaming columns in a table with a enum column is not currently supported.

注意:当前不支持使用枚举列重命名表中的列。

It doesn't matter if you're trying to change another column, if the table contains a enumanywhereit won't work. It's a Doctrine DBAL issue.

如果您尝试更改另一列并不重要,如果表中包含enum任何位置,则它不起作用。这是一个 Doctrine DBAL 问题。

As a workaround you could either drop the column and add a new one (column data will be lost):

作为一种解决方法,您可以删除该列并添加一个新列数据将丢失):

public function up()
{
    Schema::table('users', function(Blueprint $table)
    {
        $table->dropColumn('name');
    });

    Schema::table('users', function(Blueprint $table)
    {
        $table->text('username');
    });
}

or use a DB statement:

或使用 DB 语句:

public function up()
{
    DB::statement('ALTER TABLE projects CHANGE slug url VARCHAR(200)');
}

public function down()
{
    DB::statement('ALTER TABLE projects CHANGE url slug VARCHAR(200)');
}

Source: https://github.com/laravel/framework/issues/1186

来源:https: //github.com/laravel/framework/issues/1186

回答by Cengkuru Michael

A real dirty solution, that gets the job done none the less would be to

一个真正肮脏的解决方案,完成工作仍然是

update Doctrine/DBAL/Schema/MySqlSchemaManager.php 

by ading these lines just above line 113

通过在第 113 行上方添加这些行

$this->_platform->registerDoctrineTypeMapping('enum', 'string');
$type = $this->_platform->getDoctrineTypeMapping($dbType);

Beware that updating vendor files directly is not advisable because in the event the vonder chooses to update the plugin, you changes could be overwritten

请注意,不建议直接更新供应商文件,因为如果 vonder 选择更新插件,您的更改可能会被覆盖

回答by Yevgeniy Afanasyev

You should not use enum at all.Even with laravel 5.8, problem is not resolved.

你根本不应该使用枚举。即使使用 laravel 5.8,问题也没有解决。

Thank's to everyone who reminded that

感谢所有提醒这一点的人

The official Laravel 5.1 documentationstates:

Laravel 5.1 官方文档指出:

Note: Renaming columns in a table with a enum column is not currently supported.

注意:当前不支持使用枚举列重命名表中的列。

Plus you will have the same problem when adding available optionsinto enumcolumn declaration.

另外,在将可用选项添加enum列声明中时,您会遇到同样的问题。

It brings me to a conclusion that You should use enum with care.or even You should not use enum at all.

它使我得出一个结论,您应该谨慎使用 enum。甚至你根本不应该使用枚举。

I cannot vote up any answer that offer to replace enum with string. NO, you need to create a lookup table and replace enum with unsignedIntegeras a foreign key.

我不能投票赞成任何提供用字符串替换枚举的答案。不,您需要创建一个查找表并将 enum 替换unsignedIntegerforeign key.

It is a lot of work and you'll be upset doing it without previous unit-test coverage, but this is a right solution.

这是很多工作,如果没有以前的单元测试覆盖,你会很不高兴,但这是一个正确的解决方案。

You may be even fired for doing this correctly, because it is taking too long, but, don't worry, you'll find a better job. :)

你甚至可能会因为正确地做这件事而被解雇,因为它花费的时间太长,但别担心,你会找到一份更好的工作。:)

Here is an example of how difficult would it be adding available optionsinto enumcolumn declaration

这是将可用选项添加enum列声明中的难度示例

say you have this:

说你有这个:

Schema::create('blogs', function (Blueprint $table) {
    $table->enum('type', [BlogType::KEY_PAYMENTS]);
    $table->index(['type', 'created_at']);
...

and you need to make more types available

并且您需要提供更多类型

public function up(): void
{
    Schema::table('blogs', function (Blueprint $table) {
        $table->dropIndex(['type', 'created_at']);
        $table->enum('type_tmp', [
            BlogType::KEY_PAYMENTS,
            BlogType::KEY_CATS,
            BlogType::KEY_DOGS,
        ])->after('type');
    });

    DB::statement('update `blogs` as te set te.`type_tmp` = te.`type` ');

    Schema::table('blogs', function (Blueprint $table) {
        $table->dropColumn('type');
    });

    Schema::table('blogs', function (Blueprint $table) {
        $table->enum('type', [
            BlogType::KEY_PAYMENTS,
            BlogType::KEY_CATS,
            BlogType::KEY_DOGS,
        ])->after('type_tmp');
    });

    DB::statement('update `blogs` as te set te.`type` = te.`type_tmp` ');

    Schema::table('blogs', function (Blueprint $table) {
        $table->dropColumn('type_tmp');
        $table->index(['type', 'created_at']);
    });
}

回答by Hector Manuel

I get rid of this problem by creating a new Migration Class and making my migrations extending from it. Maybe there are multiple ways to make it more "standard" but this is just a very simple case which works perfectly for our team.

我通过创建一个新的迁移类并从它扩展我的迁移来解决这个问题。也许有多种方法可以使其更加“标准”,但这只是一个非常简单的案例,非常适合我们的团队。

use Doctrine\DBAL\Types\{StringType, Type};
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\{DB, Log};

/**
 * Class ExtendedMigration
 * Use it when the involved table(s) has enum type column(s)
 */
class ExtendedMigration extends Migration
{
    /**
     * ExtendedMigration constructor.
     * Handle Laravel Issue related with modifying tables with enum columns
     */
    public function __construct()
    {
        try {
            Type::hasType('enum') ?: Type::addType('enum', StringType::class);
            Type::hasType('timestamp') ?: Type::addType('timestamp', DateTimeType::class);
        } catch (\Exception $exception) {
            Log::info($exception->getMessage());
        }
    }
}

Then as explained before just extend your migration from it

然后如前所述,只需从它扩展您的迁移

class SampleMigration extends ExtendedMigration
{
    public function up()
    {
        Schema::create('invitations', function (Blueprint $table) {
            ...
            $table->enum('status', ['sent', 'consumed', 'expired'])->default('sent');
            ...
        });
    }

    public function down()
    {
        Schema::dropIfExists('invitations');
    }
}

回答by S. Mert

I think the easiest way to fix this issue is adding a mapping type to doctrine.yaml if applicable so that enum will be treated as string.

我认为解决这个问题的最简单方法是在适用的情况下向 doctic.yaml 添加映射类型,以便枚举将被视为字符串。

doctrine:
    dbal:
        #other configuration
        mapping_types:
            enum: string

回答by Ajjay Arora

You can either use the above suggestions or can add the below code to your migration file...

您可以使用上述建议,也可以将以下代码添加到您的迁移文件中...

public function up()
    {
DB::connection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');

Schema::table('<YOUR_TABLE>', function (Blueprint $table) {
//YOUR CHANGES HERE
}    
    }