Beim Ausführen von PHP Artisan Migrate wurde der folgende Fehler angezeigt
[Doctrine \ DBAL \ DBALException]
Unbekannte Datenbanktyp-Aufzählung angefordert, Doctrine \ DBAL \ Platforms \ MySqlPlatform unterstützt dies möglicherweise nicht.
So beheben Sie dieses Problem.
Code:
public function up() {
Schema::table('blogs', function (Blueprint $table) {
$table->string('wordpress_id')->nullable();
$table->string('google_blog_id')->nullable()->change();
});
}
enum
Spalte?enum
funktioniert sie nicht. Ich befürchte, dass Sie das irgendwie manuell ändern oder einige ziemlich hässliche Hacks oder Workarounds ausprobieren müssen.Antworten:
In der offiziellen Laravel 5.1- Dokumentation heißt es:
Es spielt keine Rolle, ob Sie versuchen, eine andere Spalte zu ändern. Wenn die Tabelle eine
enum
Stelle enthält, funktioniert dies nicht. Es ist ein Doctrine DBAL-Problem.Um dieses Problem zu umgehen, können Sie entweder die Spalte löschen und eine neue hinzufügen ( Spaltendaten gehen verloren ):
public function up() { Schema::table('users', function(Blueprint $table) { $table->dropColumn('name'); }); Schema::table('users', function(Blueprint $table) { $table->text('username'); }); }
oder verwenden Sie eine DB-Anweisung:
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)'); }
Quelle: https://github.com/laravel/framework/issues/1186
quelle
Schema
UmhüllungDB::statement
nicht, wenn Sie nicht verwenden$table
doctrine/dbal
dass Sie nichts tun können, was mit einer SQL-Abfrage sehr einfach zu tun ist?Es ist ein bekanntes Problem, wie in der Dokumentation zu Laravel 5.1 angegeben .
Es passiert, wenn Sie eine
enum
Spalte in Ihrer Datenbanktabelle haben. Unabhängig davon, ob Sie versuchen, eine andere Spalte umzubenennen oder eine andere Spalte in zu ändernnullable
, wird dieser Fehler angezeigt. Es ist ein Problem mitDoctrine\DBAL
.Eine einfache Lösung hierfür besteht darin, diese Konstruktormethode einfach in Ihre Datenbankmigrationsdatei einzufügen.
public function __construct() { DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string'); }
Dadurch werden alle
ENUM
Spalten zugeordnetVARCHAR()
, und die Spalte akzeptiert alle Zeichenfolgen.Dank an @ Gmatkowskis Antwort unter https://stackoverflow.com/a/32860409/1193201
quelle
AppServiceProvider::boot()
damit es funktioniert.Eine wirklich schmutzige Lösung, die die Arbeit trotzdem erledigt
durch Hinzufügen dieser Zeilen direkt über Zeile 113
$this->_platform->registerDoctrineTypeMapping('enum', 'string'); $type = $this->_platform->getDoctrineTypeMapping($dbType);
Beachten Sie, dass das direkte Aktualisieren von Herstellerdateien nicht ratsam ist, da im Falle, dass der vonder das Plugin aktualisiert, Änderungen möglicherweise überschrieben werden
quelle
protected function _getPortableDatabaseDefinition($database) { $this->_platform->registerDoctrineTypeMapping('enum', 'string'); $type = $this->_platform->getDoctrineTypeMapping($dbType); return $database['Database']; }
Ich behebe dieses Problem, indem ich eine neue Migrationsklasse erstelle und meine Migrationen von dieser aus ausdehne. Vielleicht gibt es mehrere Möglichkeiten, es "standardisierter" zu machen, aber dies ist nur ein sehr einfacher Fall, der für unser Team perfekt funktioniert.
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()); } } }
Erweitern Sie dann, wie zuvor erläutert, einfach Ihre Migration
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'); } }
quelle
app/Helpers/ExtendedMigration.php
und natürlich wird es der NamespaceApp\Helpers
Sie sollten enum überhaupt nicht verwenden. Selbst mit Laravel 5.8 ist das Problem nicht gelöst.
Vielen Dank an alle, die daran erinnert haben
In der offiziellen Laravel 5.1- Dokumentation heißt es:
Und Sie werden das gleiche Problem haben , wenn verfügbare Optionen Zugabe in
enum
Spalte Erklärung.Es bringt mich zu dem Schluss, dass Sie Enum mit Vorsicht verwenden sollten. oder sogar Sie sollten enum überhaupt nicht verwenden.
Ich kann keine Antwort auf dieses Angebot abgeben, Enum durch String zu ersetzen. NEIN, Sie müssen eine Nachschlagetabelle erstellen und die Aufzählung durch
unsignedInteger
als ersetzenforeign key
.Es ist eine Menge Arbeit und Sie werden verärgert sein, wenn Sie dies nicht ohne vorherige Berichterstattung über Unit-Tests tun, aber dies ist eine richtige Lösung.
Möglicherweise werden Sie sogar entlassen, weil Sie dies richtig gemacht haben, weil es zu lange dauert, aber keine Sorge, Sie werden einen besseren Job finden. :) :)
Hier ist ein Beispiel dafür , wie schwierig wäre es werden Optionen Zugabe in
enum
Spalte ErklärungSagen Sie, Sie haben dies:
Schema::create('blogs', function (Blueprint $table) { $table->enum('type', [BlogType::KEY_PAYMENTS]); $table->index(['type', 'created_at']); ...
und Sie müssen mehr Typen verfügbar machen
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']); }); }
quelle
Sie können entweder die obigen Vorschläge verwenden oder den folgenden Code zu Ihrer Migrationsdatei hinzufügen ...
public function up() { DB::connection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string'); Schema::table('<YOUR_TABLE>', function (Blueprint $table) { //YOUR CHANGES HERE } }
quelle
Ich denke, der einfachste Weg, um dieses Problem zu beheben, ist das Hinzufügen eines Zuordnungstyps zu doctrine.yaml, falls zutreffend, damit enum als Zeichenfolge behandelt wird.
doctrine: dbal: #other configuration mapping_types: enum: string
quelle
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'); }
quelle