Laravel 5.1 Migration and Seeding Cannot truncate a table referenced in a foreign key constraint

前端 未结 9 2140
借酒劲吻你
借酒劲吻你 2020-12-15 05:04

I\'m trying to run the migration (see below) and seed the database, but when I run

php artisan migrate --seed

I get this error:

<         


        
相关标签:
9条回答
  • 2020-12-15 05:15

    You could just drop it with.

    $table->dropForeign('posts_user_id_foreign');

    0 讨论(0)
  • 2020-12-15 05:17

    you can use

    DB::table('your_table_name')->delete();
    

    to empty a table, this won't delete the table structure. But the auto increment id will not start from initial number.

    0 讨论(0)
  • 2020-12-15 05:17

    Here is what works for me every time. When you're adding the foreign key, make sure to add cascade. the syntax is like this

    $table->foreign('column')->references('id')->on('table_name')->onDelete('cascade');
    

    Make sure to replace id with whatever field is applicable for you.

    Now before running the seeding add this instead of trucate

    DB::statement('DELETE FROM table_name');
    

    It will delete all the data. Hope this helps.

    0 讨论(0)
  • 2020-12-15 05:21

    As the error says, you can not truncate tables referenced by foreign keys. Delete should work though...

    DB::table('some_table')->delete();
    
    0 讨论(0)
  • 2020-12-15 05:25
    DB::statement('SET FOREIGN_KEY_CHECKS=0;');
    App\User::truncate();
    DB::statement('SET FOREIGN_KEY_CHECKS=1;');
    

    And it works!

    0 讨论(0)
  • 2020-12-15 05:30

    I faced the same issue with my Role and Permission setup and this is what I did that worked as I wanted. Truncate() will reset the Increment column to 1 but throw a foreign key error while delete on the other hand works fine but doesn't reset the increment column, so I did the following in my Seeder's file (i.e RoleSeeder.php in my case)

    1. [ delete() method ]

    $roles = [];
    
    ... // Some foreach statement to prepare an array of data for DB insert()
    
    // Delete and Reset Table
    DB::table('roles')->delete();
    DB::statement("ALTER TABLE `roles` AUTO_INCREMENT = 1");
    // Insert into table
    DB::table('roles')->insert($roles);
    

    This will cascade all other child tables attached to the roles table. in my case users_roles table. This way I avoided disabling and enabling foreign key checks.

    2. Something to put in mind / Second Approach [ truncate() method ]

    if you don't have the intention of deleting all the data stored in the child's table (in my case users_roles table) ... You can go with truncate() and then in the DatabaseSeeders.php file you disable and enable foreign key check. As I tested this and the users_roles data was intact, the seed on affected roles table.

    //RoleSeeders.php File
    
    $roles = [];
    
    ... // Some foreach statement to prepare an array of data for DB insert()
    
    // Truncate Table
    DB::table('roles')->truncate();
    // Insert into table
    DB::table('roles')->insert($roles);
    

    Then in the DatabaseSeeder.php file, you do;

    public function run()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS=0;');
    
        $this->call([
            RoleSeeder::class,
        ]);
    
        DB::statement('SET FOREIGN_KEY_CHECKS=1;');
    }
    

    But I prefer the delete() method better, since I don't have to disable/enable the foreign key check

    0 讨论(0)
提交回复
热议问题