web-dev-qa-db-fra.com

Laravel Changement de migration pour rendre une colonne nullable

J'ai créé une migration avec unsigned user_id. Comment puis-je éditer user_id dans une nouvelle migration pour la rendre également nullable()?

Schema::create('throttle', function(Blueprint $table)
{
    $table->increments('id');
    // this needs to also be nullable, how should the next migration be?
    $table->integer('user_id')->unsigned();
}
160
user391986

Laravel 5 prend désormais en charge le changement de colonne.

Exemple de doc officiel

Schema::table('users', function($table)
{
    $table->string('name', 50)->nullable()->change();
});

source: http://laravel.com/docs/5.0/schema#changing-columns

Laravel 4 ne supporte pas la modification de colonne. Vous devez écrire une commande sql brute.

  // getting Laravel App Instance
   $app = app();

  // getting laravel main version
   $laravelVer = explode('.',$app::VERSION);

    switch ($laravelVer[0]) {

        case('5') :                
            Schema::table('pro_categories_langs', function(Blueprint $t) {
                $t->string('name', 100)->nullable()->default(null)->change();
            });               
            break;                
        /**
         * it is not L5 !!
         */
        default :                
             DB::statement('ALTER TABLE `pro_categories_langs` MODIFY `name` VARCHAR(100) NULL;');                                  
    }
202
MURATSPLAT

Je suppose que vous essayez de modifier une colonne sur laquelle vous avez déjà ajouté des données. Il est donc impossible de supprimer une colonne et de l'ajouter à nouveau en tant que colonne Nullable sans perdre des données. Nous allons alter la colonne existante.

Cependant, le générateur de schéma de Laravel ne prend pas en charge la modification de colonnes autre que le changement de nom de la colonne. Vous devrez donc exécuter des requêtes brutes pour les faire, comme ceci:

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
}

Et pour vous assurer que vous pouvez toujours annuler votre migration, nous allons également procéder à la down().

function down()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

Une remarque est que puisque vous convertissez entre nullable et non nullable, vous devez vous assurer de nettoyer les données avant/après votre migration. Faites donc cela dans votre script de migration dans les deux sens:

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
    DB::statement('UPDATE `throttle` SET `user_id` = NULL WHERE `user_id` = 0;');
}

function down()
{
    DB::statement('UPDATE `throttle` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}
149
Unnawut

Voici la réponse complète pour le futur lecteur. Notez que cela n’est possible que dans Laravel 5+.

Tout d’abord, vous aurez besoin du paquet doctrine/dbal:

composer require doctrine/dbal

Maintenant, dans votre migration, vous pouvez faire cela pour rendre la colonne nullable:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

Vous vous demandez peut-être comment annuler cette opération. Malheureusement, cette syntaxe n'est pas supportée:

// Sadly does not work :'(
$table->integer('user_id')->unsigned()->change();

C'est la syntaxe correcte pour inverser la migration:

$table->integer('user_id')->unsigned()->nullable(false)->change();

Ou, si vous préférez, vous pouvez écrire une requête brute:

public function down()
{
    /* Make user_id un-nullable */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

J'espère que vous trouverez cette réponse utile. :)

148
Dmitri Chebotarev

Il est la migration complète pour Laravel 5:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable()->change();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable(false)->change();
    });
}

Le fait est que vous pouvez supprimer nullable en passant false comme argument.

39
Yauheni Prakopchyk

Si vous changez les colonnes et êtes tombé sur

'Doctrine\DBAL\Driver\PDOMySql\Driver' not found

alors il suffit d'installer

composer require doctrine/dbal

15
ken

Ajoutant à la réponse de Dmitri Chebotarev, comme pour Laravel 5+.

Après avoir requis le paquet doctrine/dbal:

composer require doctrine/dbal

Vous pouvez ensuite effectuer une migration avec des colonnes nullables, comme suit:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

Pour annuler l'opération, faites:

public function down()
{
    /* turn off foreign key checks for a moment */
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');
    /* set null values to 0 first */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    /* alter table */
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
    /* finally turn foreign key checks back on */
    DB::statement('SET FOREIGN_KEY_CHECKS = 1');

}

5
rzb

Ajout à la réponse de Dmitri Chebotarev,

Si vous souhaitez modifier plusieurs colonnes à la fois, vous pouvez le faire comme ci-dessous

DB::statement('
     ALTER TABLE `events` 
            MODIFY `event_date` DATE NOT NULL,
            MODIFY `event_start_time` TIME NOT NULL,
            MODIFY `event_end_time` TIME NOT NULL;
');
3
Sameer

Pour Laravel 4.2, la réponse de Unnawut ci-dessus est la meilleure. Mais si vous utilisez le préfixe de table, vous devez modifier légèrement votre code.

function up()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE `' . $table_prefix . 'throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
}

Et pour vous assurer que vous pouvez toujours annuler votre migration, nous allons également procéder à la down().

function down()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE `' . $table_prefix . 'throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}
3
Debiprasad

Essayez le:

$table->integer('user_id')->unsigned()->nullable();
2
Adil