在运行 php artisan migrate 时,我收到以下错误
[学说\ DBAL \ DBALException]
请求未知的数据库类型枚举,Doctrine \ DBAL \ Platforms \ MySqlPlatform可能不支持它。
如何解决此问题。
代码:
public function up() {
Schema::table('blogs', function (Blueprint $table) {
$table->string('wordpress_id')->nullable();
$table->string('google_blog_id')->nullable()->change();
});
}
答案 0 :(得分:62)
这是Laravel 5.1 documentation中所述的已知问题。
注意:目前不支持重命名表中包含
enum
列的列。
当数据库表中有nullable
列时会发生这种情况。无论您是要重命名其他列,还是将其他列更改为Doctrine\DBAL
,都会显示此错误。这是public function __construct()
{
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
}
的问题。
轻松修复就是在数据库迁移文件中添加此构造函数方法。
ENUM
这会将所有VARCHAR()
列映射到{{1}},该列将接受任何字符串。
这对Laravel 5.1和Laravel 5.3起作用。我希望很快就能解决这个问题。
感谢@ Gmatkowski的答案 https://stackoverflow.com/a/32860409/1193201
答案 1 :(得分:57)
官方Laravel 5.1 documentation声明:
注意:目前不支持使用枚举列重命名表中的列。
如果您尝试更改其他列,则无关紧要,如果该表包含enum
任何地方,则无效。这是一个Doctrine DBAL问题。
作为一种解决方法,您可以删除该列并添加一个新列(列数据将丢失):
public function up()
{
Schema::table('users', function(Blueprint $table)
{
$table->dropColumn('name');
});
Schema::table('users', function(Blueprint $table)
{
$table->text('username');
});
}
或使用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)');
}
答案 2 :(得分:3)
真正的肮脏解决方案,无论如何都能完成工作
update Doctrine/DBAL/Schema/MySqlSchemaManager.php
将这些线放在第113行上方
$this->_platform->registerDoctrineTypeMapping('enum', 'string');
$type = $this->_platform->getDoctrineTypeMapping($dbType);
请注意不建议直接更新供应商文件,因为如果vonder选择更新插件,您的更改可能会被覆盖
答案 3 :(得分:3)
您可以使用以上建议,也可以将以下代码添加到迁移文件中...
JsonView
答案 4 :(得分:2)
我通过创建一个新的迁移类并从该类进行扩展来摆脱了这个问题。也许有多种方法可以使它更“标准”,但这只是一个非常简单的案例,对我们的团队来说是完美的。
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());
}
}
}
然后如前所述,只是从中扩展迁移
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');
}
}
答案 5 :(得分:0)
您完全不应使用枚举。即使使用laravel 5.8,问题也无法解决。
感谢所有提醒我的人
Laravel 5.1 documentation官方声明:
注意:当前不支持使用enum列重命名表中的列。
我需要补充的是,在向enum
列声明中添加可用选项时,您也会遇到同样的问题。
我得出的结论是,您应谨慎使用枚举。甚至您根本不应使用枚举。
我无法投票通过字符串替换枚举的任何答案。否,您需要创建一个查找表,并用unsignedInteger
作为foreign key
替换枚举。
这是很多工作,如果没有单元测试,您会很烦恼,但这是一个正确的解决方案。
您可能会因为正确执行此操作而被解雇,因为这花费了太长时间,但是,不用担心,您会找到更好的工作。 :)
下面是一个例子,说明如何在向enum
列声明中添加可用选项
说你有这个:
Schema::create('blogs', function (Blueprint $table) {
$table->enum('type', [BlogType::KEY_PAYMENTS]);
$table->index(['type', 'created_at']);
...
并且您需要提供更多类型
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']);
});
}
答案 6 :(得分:0)
我认为解决此问题的最简单方法是在doctrine.yaml中添加一个映射类型(如果适用),以便将枚举视为字符串。
doctrine:
dbal:
#other configuration
mapping_types:
enum: string
答案 7 :(得分:0)
Laravel:5.8
use Doctrine\DBAL\Types\StringType;
use Illuminate\Support\Facades\DB;
public function __construct()
{
if (! Type::hasType('enum')) {
Type::addType('enum', StringType::class);
}
// For point types
//DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('point', 'string');
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
}