Laravel Eloquent 截断 - 外键约束
Laravel Eloquent truncate - Foreign key constraint
我在使用 Laravel 5 删除数据时遇到一些问题。我似乎卡在 'foreign key constraint' 上,但我不明白为什么。
在我当前的数据库模型中,我有一个数据点 table,它有一个传感器的外键 table(datapoints.sensors_id -> sensor.id)。
我正在尝试的代码:
Route::get('/truncateData', function() {
DB::table('datapoints')->truncate();
DB::table('sensors')->truncate();
return 'Done...';
});
结果:
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot
truncate a table referenced in a foreign key constraint
(alerting
.datapoints
, CONSTRAINT datapoints_sensor_id_foreign
FOREIGN KEY (sensor_id
) REFERENCES alerting
.sensors
(id
))
(SQL: truncate sensors
)
如果顺序相反(首先删除传感器),我会理解这个约束,但是当数据点为空时,删除传感器应该没有问题吗?我也试过:
DB::table('datapoints')->delete();
DB::table('sensors')->delete();
return 'Done...';
最后我还尝试在删除语句之间显式添加 'DB::commit()',但所有 return 结果相同。
这是正常行为吗?我错过了什么吗?
不,这是您的数据库的工作方式。您不能截断被其他 table 引用的 table。你可以做类似
的事情
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
DB::table('datapoints')->truncate();
DB::table('sensors')->truncate();
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
要禁用外键检查,截断 tables 并再次启用它。
如果您更喜欢使用 Eloquent 对象,Maksym 的回答是 "Eloquent" 方式
use Illuminate\Support\Facades\Schema;
use App\Models\Datapoint;
use App\Models\Sensor;
Schema::disableForeignKeyConstraints();
Datapoint::truncate();
Sensor::truncate();
Schema::enableForeignKeyConstraints();
在Laravel 7和8中,为了兼容4个数据库(MySql,Postgres、SQLite 和 SqlServer) 而没有 Eloquent,你可以使用:
Schema::disableForeignKeyConstraints();
DB::table('datapoints')->truncate();
DB::table('sensors')->truncate();
Schema::enableForeignKeyConstraints();
我在使用 Laravel 5 删除数据时遇到一些问题。我似乎卡在 'foreign key constraint' 上,但我不明白为什么。
在我当前的数据库模型中,我有一个数据点 table,它有一个传感器的外键 table(datapoints.sensors_id -> sensor.id)。
我正在尝试的代码:
Route::get('/truncateData', function() {
DB::table('datapoints')->truncate();
DB::table('sensors')->truncate();
return 'Done...';
});
结果:
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint (
alerting
.datapoints
, CONSTRAINTdatapoints_sensor_id_foreign
FOREIGN KEY (sensor_id
) REFERENCESalerting
.sensors
(id
)) (SQL: truncatesensors
)
如果顺序相反(首先删除传感器),我会理解这个约束,但是当数据点为空时,删除传感器应该没有问题吗?我也试过:
DB::table('datapoints')->delete();
DB::table('sensors')->delete();
return 'Done...';
最后我还尝试在删除语句之间显式添加 'DB::commit()',但所有 return 结果相同。
这是正常行为吗?我错过了什么吗?
不,这是您的数据库的工作方式。您不能截断被其他 table 引用的 table。你可以做类似
的事情DB::statement('SET FOREIGN_KEY_CHECKS=0;');
DB::table('datapoints')->truncate();
DB::table('sensors')->truncate();
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
要禁用外键检查,截断 tables 并再次启用它。
如果您更喜欢使用 Eloquent 对象,Maksym 的回答是 "Eloquent" 方式
use Illuminate\Support\Facades\Schema;
use App\Models\Datapoint;
use App\Models\Sensor;
Schema::disableForeignKeyConstraints();
Datapoint::truncate();
Sensor::truncate();
Schema::enableForeignKeyConstraints();
在Laravel 7和8中,为了兼容4个数据库(MySql,Postgres、SQLite 和 SqlServer) 而没有 Eloquent,你可以使用:
Schema::disableForeignKeyConstraints();
DB::table('datapoints')->truncate();
DB::table('sensors')->truncate();
Schema::enableForeignKeyConstraints();