Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Truncate tables with foreign key constraints in a Laravel seed file.

For the scenario, imagine posts has a foreign key user_id referencing users.id

public function up()
{
	Schema::create('posts', function(Blueprint $table) {
		$table->increments('id');
		$table->string('title');
		$table->text('body');
		$table->integer('user_id')->unsigned();
		$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
		$table->timestamps();
	});
}

running seeds with truncate() will trigger a constraint violation if foreign key checks is not disabled.

	Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint ...

The fix:

DatabaseSeeder.php

class DatabaseSeeder extends Seeder {

	/**
	 * Run the database seeds.
 	 *
	 * @return void
	 */
	public function run()
	{
		Eloquent::unguard();

		//disable foreign key check for this connection before running seeders
		DB::statement('SET FOREIGN_KEY_CHECKS=0;');
			
		$this->call('UsersTableSeeder');
		$this->call('PostsTableSeeder');

		// supposed to only apply to a single connection and reset it's self
		// but I like to explicitly undo what I've done for clarity
		DB::statement('SET FOREIGN_KEY_CHECKS=1;');
		
	}

}

fix from here http://stackoverflow.com/questions/14666277/laravel-4-working-with-relationships-in-seeds

As pointed out in the comments at SO you wouldn't want to disable foreign key checks on a production app but you really don't want to run seed files in production either so obviously this is not intended for production but helpful in development.

@igorbabko
Copy link

igorbabko commented May 21, 2016

Great! Thanks.

@Srivani17
Copy link

Srivani17 commented Jun 21, 2016

Tank you

@LeonSkrilec
Copy link

LeonSkrilec commented Jun 28, 2016

Thanks for that!

@natalia-stovbun
Copy link

natalia-stovbun commented Jul 7, 2016

It works! Thanks!

@kriskornel
Copy link

kriskornel commented Jul 25, 2016

Yup. It works for me too

@IProSoft
Copy link

IProSoft commented Aug 18, 2016

Thanks for tip!

@achintharodrigo
Copy link

achintharodrigo commented Oct 9, 2016

Thanks.

@j3rrey
Copy link

j3rrey commented Nov 14, 2016

thx!

@mikedamoiseau
Copy link

mikedamoiseau commented Jan 24, 2017

This code seems to work too (MySQL, Laravel 5.2.45):

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

@umutyerebakmaz
Copy link

umutyerebakmaz commented Mar 4, 2017

Good experience thank u

@zachu90
Copy link

zachu90 commented May 7, 2017

Thanks this worked for me!

@hatamiarash7
Copy link

hatamiarash7 commented May 27, 2017

Awesome :) i have many problems in last 30 minute 👍 💯

@blues911
Copy link

blues911 commented Jun 20, 2017

Tested in Laravel4, Thanks a lot)

@ggwebdev
Copy link

ggwebdev commented Jul 6, 2017

Works great now! Tanks

@SOSTheBlack
Copy link

SOSTheBlack commented Nov 26, 2017

Muito Obrigado!

@tahiryasin
Copy link

tahiryasin commented Jan 30, 2018

@mikedamoiseau You are the man ! 👍 💯

@ogigpermana
Copy link

ogigpermana commented May 4, 2018

@mikedamoiseau Thanks sir this is works great!

@serdarsen
Copy link

serdarsen commented May 21, 2018

Thank you!

@ezequiel9
Copy link

ezequiel9 commented Aug 2, 2018

Great man!

@micessien
Copy link

micessien commented Nov 16, 2018

Thank you!

@yunusemremert
Copy link

yunusemremert commented Mar 5, 2019

thank you bro!

@M-Abdullahi
Copy link

M-Abdullahi commented Apr 16, 2019

Another option would be to use the schema facade to disable the fk constraint.

``
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::disableForeignKeyConstraints();
Schema::dropIfExists('organisation_addresses');
Schema::enableForeignKeyConstraints();
}


I was also thinking on the idea of creating 2 separate migrations; 
one to disable and another one to enable the fk constraints. 

You can edit the timestamp naming part and place the fk enabling migration to 
run as the _first_ migration and the disabling one to run _last_ after  all other migrations have run. 

~  a thought that i haven't tried, yet.

FYI: I use mysql and do this on development environment 

@MutlaqAldhbuiub
Copy link

MutlaqAldhbuiub commented Dec 17, 2019

Thanks!
It works for me!

@yunuselci
Copy link

yunuselci commented Jan 14, 2020

thx! works for me too

@Amvos2000
Copy link

Amvos2000 commented Jan 17, 2020

Thx this saved my project

@RyotaBannai
Copy link

RyotaBannai commented May 15, 2020

@mikedamoiseau thank you!!

@edrisaturay
Copy link

edrisaturay commented May 23, 2020

Thanks for this fix. works on laravel 7

@pishguy
Copy link

pishguy commented May 29, 2020

you can use this code on Laravel 7

Schema::disableForeignKeyConstraints();

$this->call(UserTableSeeder::class);
$this->call(LanguageTableSeeder::class);

Schema::enableForeignKeyConstraints();

@henryavila
Copy link

henryavila commented Sep 4, 2020

Hi, I have this problem in MsSQL, and I conclude that I have just 2 options (beside moving away from MSSQL =D)

  1. Remove the foreign key, truncate and recreate the foreign key
  2. Delete table data and reset the Auto increment

I Found the approach 2 much better. Here is the working code:

$tableName = (new Model())->getTable();
\Illuminate\Support\Facades\DB::table($tableName )->delete();
\Illuminate\Support\Facades\DB::statement("DBCC CHECKIDENT ({$tableName }, RESEED, 0)");

Baiscally its what the truncate does (obviously the truncate is much faster), But it work.

@remusbejusca87
Copy link

remusbejusca87 commented Mar 31, 2022

thanks man, it worked for me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment