web-dev-qa-db-fra.com

Laravel 5.1 Énumération de type de base de données inconnue demandée

En exécutant php artisan migrate , j'ai l'erreur suivante

[Doctrine\DBAL\DBALException]
Enum demandé le type de base de données inconnu demandé, Doctrine\DBAL\Platforms\MySqlPlatform peut ne pas le prendre en charge. 

Comment résoudre ce problème.

Code:

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

Le document officiel Laravel 5.1 documentation indique:

Remarque: Le changement de nom des colonnes dans une table avec une colonne enum n'est pas pris en charge actuellement.

Peu importe que vous essayiez de changer une autre colonne, si la table contient une enumn'importe où _ cela ne fonctionnera pas. C'est un problème de Doctrine DBAL.

Pour contourner le problème, vous pouvez soit supprimer la colonne et en ajouter une nouvelle (les données de la colonne seront perdues):

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

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

ou utilisez une instruction 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

49
Adrenaxus

C'est un problème connu comme indiqué dans Laravel 5.1 documentation .

Remarque: le fait de renommer des colonnes dans une table avec une colonne enum n'est actuellement pas pris en charge.

Cela se produit lorsque vous avez une colonne enum dans votre table de base de données. Que vous essayiez de renommer une autre colonne ou de changer une autre colonne en nullable, ce bogue apparaîtra. C'est un problème avec Doctrine\DBAL

Un correctif easy pour cela consiste simplement à ajouter cette méthode de constructeur dans votre fichier de migration de base de données.

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

Cela mappera toutes les colonnes ENUM sur VARCHAR(), et la colonne acceptera toute chaîne.

Cela a fonctionné pour moi sur Laravel 5.1 et Laravel 5.3. J'espère que ce bug pourra être corrigé bientôt.

Merci à la réponse de @ Gmatkowski àhttps://stackoverflow.com/a/32860409/1193201

53
Xeleon

Une vraie solution sale, qui fait le travail tout de même serait de

update Doctrine/DBAL/Schema/MySqlSchemaManager.php 

en ajoutant ces lignes juste au-dessus de la ligne 113

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

Attention, il est déconseillé de mettre à jour directement les fichiers du fournisseur, car si vonder décidait de mettre à jour le plug-in, vos modifications pourraient être écrasées.

3
Cengkuru Michael

Je me débarrasse de ce problème en créant une nouvelle classe de migration et en prolongeant mes migrations. Il y a plusieurs façons de faire plus "standard" mais il ne s'agit que d'un cas très simple qui fonctionne parfaitement pour moi.

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 {
            DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
            Type::addType('enum', StringType::class);
        } catch (\Exception $exception) {
            Log::info($exception->getMessage());
        }
    }
}

Ensuite, comme expliqué précédemment, prolongez simplement votre 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');
    }
}
1
Hector Manuel