Php 列已存在:当通过迁移修改列以在Laravel中具有唯一索引时为1060
今天我试图在我的一个表中为slug创建一个字符串列。我要求该列具有唯一索引,但该表已经有信息,因此,在创建该列时,我收到一条错误消息,通知我新列中存在重复值和空值Php 列已存在:当通过迁移修改列以在Laravel中具有唯一索引时为1060,php,laravel,database-migration,laravel-6,Php,Laravel,Database Migration,Laravel 6,今天我试图在我的一个表中为slug创建一个字符串列。我要求该列具有唯一索引,但该表已经有信息,因此,在创建该列时,我收到一条错误消息,通知我新列中存在重复值和空值 public function up(){ Schema::table( 'states', function( Blueprint $table ){ $table->string( 'slug', 128 )->unique(); } ); } 因为slug将包含“name”列的slugized版本,
public function up(){
Schema::table( 'states', function( Blueprint $table ){
$table->string( 'slug', 128 )->unique();
} );
}
因为slug将包含“name”列的slugized版本,所以我决定分两步创建该列。首先,该列将是一个常规列,我将使用Str::slug()遍历所有记录,创建正确的slug值。之后,我将修改该列以添加unique()选项,如下所示:
我认为这是一个很好的解决方案,因为我不会破坏数据库中的任何规则,因为所有的名称都不同。我运行了迁移,得到了一个很好的错误:
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'slug' (SQL: alter table `states` add `slug` varchar(128) not null)
有没有关于如何正确创建迁移的想法?更改行:
$table->string( 'slug', 128 )->unique()->change();
到
总而言之:
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' );
} );
}
请参阅。这里有两个问题,一个是添加重复列并应用唯一索引,另一个可能是Str::slug方法中的冲突 在添加列或唯一索引之前,请检查它是否不存在
public function up() {
\DB::transaction(function() {
if (!Schema::hasColumn('states', 'slug')) {
Schema::table('states', function (Blueprint $table) {
$table->string('slug', 128);
$table->unique('slug', 'unique_slug_index');
});
}
$states = State::all();
foreach( $states as $state ){
$state->slug = Str::slug( $state->name );
$state->save();
}
});
}
\DB:transaction()
失败了
在尝试了#的答案但没有成功后(我一直得到相同的错误),我开始怀疑问题是否是我所有的列修改都是在同一个方法函数(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();
} );
}
这个版本的代码是成功的,顺便说一下,#的建议也是正确的,我测试了$table->unique('slug')代码>与我的方法,它也工作
public function up() {
\DB::transaction(function() {
if (!Schema::hasColumn('states', 'slug')) {
Schema::table('states', function (Blueprint $table) {
$table->string('slug', 128);
$table->unique('slug', 'unique_slug_index');
});
}
$states = State::all();
foreach( $states as $state ){
$state->slug = Str::slug( $state->name );
$state->save();
}
});
}
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();
} );
}