Столбец уже существует: 1060 при изменении столбца, чтобы иметь уникальный индекс в Laravel с миграциями - PullRequest
1 голос
/ 09 апреля 2020

Сегодня я пытался создать строковый столбец для пули в одной из моих таблиц. Мне потребовалось, чтобы столбец имел уникальный индекс, но в таблице уже была информация, поэтому в момент создания столбца я получил сообщение об ошибке, информирующее меня о повторяющихся и пустых значениях в новом столбце.

public function up(){
  Schema::table( 'states', function( Blueprint $table ){
    $table->string( 'slug', 128 )->unique();
  } );
}

Так как слаг будет содержать слаганную версию столбца «имя», я решил создать столбец в два этапа. Сначала этот столбец должен был быть обычным, и я собирался циклически проходить по всем записям, создавая правильное значение слага, используя Str :: slug (). После этого я собирался изменить столбец, добавив параметр unique (), следуя документации Laravel :

public function up(){
  Schema::table( 'states', function( Blueprint $table ){
    $table->string( 'slug', 128 );
    $states = State::all();
    foreach( $states as $state ){
      $state->slug = Str::slug( $state->name );
      $state->save();
    }
    $table->string( 'slug', 128 )->unique()->change();
  } );
}

Я подумал, что это хорошее решение, потому что я не собирался нарушать никаких правил в моей базе данных, так как все имена были разными. Я запустил миграцию и получил приятную ошибку:

SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'slug' (SQL: alter table `states` add `slug` varchar(128) not null)

Есть идеи, как правильно создать миграцию?

Ответы [ 3 ]

1 голос
/ 10 апреля 2020

После попытки ответа * DigitalDrifter безуспешно (я продолжал получать ту же ошибку), я начал задаваться вопросом, была ли проблема в том, что все мои модификации столбцов были выполнены внутри одного и того же метода function( Blueprint $table ), поэтому Я решил разделить процесс на 3 этапа следующим образом:

public function up(){
  Schema::table( 'states', function( Blueprint $table ){
    $table->string( 'slug', 128 );
  } );

  $states = State::all();
  foreach( $states as $state ){
    $state->slug = Str::slug( $state->state );
    $state->save();
  }

  Schema::table( 'states', function( Blueprint $table ){
    $table->string( 'slug', 128 )->unique()->change();
  } );
}

Эта версия моего кода была успешной, кстати, предложение # DigitalDrifter также было правильным, я проверил $table->unique( 'slug' ); с моим подходом, и это тоже работает.

1 голос
/ 09 апреля 2020

Изменить строку:

$table->string( 'slug', 128 )->unique()->change();

на

$table->unique( 'slug' );

Все вместе:

public function up(){
  Schema::table( 'states', function( Blueprint $table ){
    $table->string( 'slug', 128 );

    foreach( State::all() as $state ){
      $state->update(['slug' => = Str::slug( $state->name )]);
    }

    $table->unique( 'slug' );
  } );
}

См. https://laravel.com/docs/7.x/migrations#creating -индекс .

0 голосов
/ 10 апреля 2020

Здесь есть две проблемы, одна из них - добавление дублирующего столбца и применение уникального индекса , а вторая, возможно, столкновение в методе Str :: slug

перед добавление столбца или уникального индекса для проверки, если он еще не существует

...