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个数据库(MySqlPostgresSQLiteSqlServer) 而没有 Eloquent,你可以使用:

Schema::disableForeignKeyConstraints();
DB::table('datapoints')->truncate();
DB::table('sensors')->truncate();
Schema::enableForeignKeyConstraints();