对数据库迁移的Laravel Integrity约束违规

时间:2016-09-03 21:31:54

标签: laravel laravel-5 database-migration laravel-5.3

SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table `users`)

我知道这已经多次回答了,但我仍然无法弄清楚我的迁移是什么问题。

首先,我致电合作伙伴迁移

public function up()
{
    Schema::create('partners', function (Blueprint $table) {
        $table->engine = 'InnoDB';
        $table->increments('id');
        $table->integer('admin_id')->unsigned();
        $table->string('company_name', 50);
        ...
}
public function down()
{
    Schema::drop('partners');
}

然后我调用用户迁移

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->engine = 'InnoDB';
        $table->increments('id');
        $table->integer('partner_id')->unsigned();
        $table->string('email', 70)->unique();
        $table->string('first_name', 50);
        $table->string('last_name', 50);
        $table->string('password', 60);
        $table->string('image', 200)->nullable();
        $table->string('gender', 10)->nullable();
        $table->string('phone', 25)->nullable();
        $table->string('nationality', 50)->nullable();
        $table->string('address', 200)->nullable();
        $table->boolean('is_active')->default(0);
        $table->string('single_signon', 30)->nullable();

        // Checks if mysql or mariadb supports json data type
        if ((DB::connection()->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') && version_compare(DB::connection()->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), '5.7.8', 'ge')) {
            $table->json('settings')->nullable();
        } else {
            $table->text('settings')->nullable();
        }

        $table->softDeletes();
        $table->rememberToken();
        $table->timestamps();
        $table->foreign('partner_id')->references('id')->on('partners')->onDelete('cascade');
    });
}

public function down()
{
    Schema::table('users', function(Blueprint $table) {
        $table->dropForeign('users_partner_id_foreign');
    });

    Schema::drop('users');
}

最后我致电通知迁移:

public function up()
    {
        Schema::create('notifications', function (Blueprint $table) {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->string('notification_type', 10);

            // Checks if mysql or mariadb supports json data type
            if ((DB::connection()->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') && version_compare(DB::connection()->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), '5.7.8', 'ge')) {
                $table->json('notification')->nullable();
            } else {
                $table->text('notification')->nullable();
            }
            $table->boolean('seen');
            $table->timestamps();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });
    }
public function down()
{
    Schema::table('notifications', function(Blueprint $table) {
        $table->dropForeign('notifications_user_id_foreign');
    });
    Schema::drop('notifications');
}

有人能弄清楚这有什么不对吗?我正在使用laravel 5.3和php7

2 个答案:

答案 0 :(得分:0)

问题在于迁移顺序。最好将迁移包含在一个文件中,然后将子项放在父文件之前,如下所示:

public function down(){
  Schema::drop('notifications');
  Schema::drop('users');
  Schema::drop('partners');
}

这是因为Laravel试图在users表之前删除notifications表,其中包括在user_id表中引用的users列。

答案 1 :(得分:0)

private static final String USER_RATE_LIMIT_EXCEEDED_REASON = "userRateLimitExceeded";
private static final String RATE_LIMIT_EXCEEDED_REASON = "rateLimitExceeded";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

private boolean isRateLimitExceeded(HttpResponse response) {
    return response.getStatusCode() == HttpStatusCodes.STATUS_CODE_FORBIDDEN
            && isRateLimitExceeded(GoogleJsonResponseException.from(JSON_FACTORY, response));
}

private boolean isRateLimitExceeded(GoogleJsonResponseException ex) {
    if (ex.getDetails() == null || CollectionUtils.isEmpty(ex.getDetails().getErrors())) {
        return false;
    }
    String reason = ex.getDetails().getErrors().get(0).getReason();
    return RATE_LIMIT_EXCEEDED_REASON.equals(reason) || USER_RATE_LIMIT_EXCEEDED_REASON.equals(reason);
}

在删除表时禁用外键检查