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();
}
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;');
}
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;');
}
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. :)
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.
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
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');
}
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;
');
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;');
}
Essayez le:
$table->integer('user_id')->unsigned()->nullable();