Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardized way to disable foreign key constraints #2502

Closed
RSully opened this issue Oct 16, 2013 · 8 comments
Closed

Standardized way to disable foreign key constraints #2502

RSully opened this issue Oct 16, 2013 · 8 comments

Comments

@RSully
Copy link
Contributor

RSully commented Oct 16, 2013

I am having an issue with disabling foreign key checks differently in my different environments. I am trying to use SQLite for testing and MySQL for development/production. Each has their own way to disable foreign key checks.


MySQL:

DB::statement('SET FOREIGN_KEY_CHECKS = 0');

SQLite:

DB::statement('PRAGMA foreign_keys = OFF');
@taylorotwell
Copy link
Member

We would need to implement this at the Schema builder layer. Even then I'm not sure we can do it easily across all platforms.

@RSully
Copy link
Contributor Author

RSully commented Oct 17, 2013

Some info I have found (mostly unverified/untested) for each of the PDO drivers.

-- Disable checks:
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all";
-- Enable checks:
EXEC sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all";
  • MySQL:
-- Disable checks:
SET FOREIGN_KEY_CHECKS = 0;
-- Enable checks:
SET FOREIGN_KEY_CHECKS = 1;
  • SQLite:
-- Disable checks:
PRAGMA foreign_keys = OFF;
-- Enable checks:
PRAGMA foreign_keys = ON;
  • 4D:
-- Disable checks:
ALTER DATABASE DISABLE CONSTRAINTS;
-- Enable checks:
ALTER DATABASE ENABLE CONSTRAINTS;
  • CUBRID link a: Does not provide a hack to disable foreign key checks
  • Firebird link a: Couldn't find an example but since 2.1 it may be possible.
  • IBM: couldn't find any good info
  • Informix link a, link b: Not sure, looks possible maybe
  • Oracle link a: Looks possible maybe
  • PostgreSQL link a: table by table

@ikari7789
Copy link
Contributor

Wouldn't it be possible to implement this at the DB facade level?

 DB::disableForeignKeyCheck()
 DB::enableForeignKeyCheck()

And have it work on each separate DB engine in it's own engine-specific way, if any. If no specific way to do it, then simply do nothing?

@nicogominet
Copy link

+1
I totally agree with @ikari7789 this should be implemented on the DB class/façade.

@yahya-uddin
Copy link

When I tried DB::disableForeignKeyCheck(), it dosen't seem to work. Has this actually been added???

@darrensapalo
Copy link

@anik786 No, it isn't implemented yet, as proven by a simple "Find in all files" search within the repository.

The alternative is to use the code posted by the original poster/reporter depending on your sql server.

In my case, I use MySQL, so I use the following:
DB::statement('SET FOREIGN_KEY_CHECKS = 0');

@CLOUGH
Copy link

CLOUGH commented Feb 25, 2016

1+ for @ikari7789 DB::disableForeignKeyCheck() DB::enableForeignKeyCheck()

@CLOUGH
Copy link

CLOUGH commented Feb 25, 2016

Currently experiencing this issue in 5.1 so i have a little workaround inusing for the time being on till Taylor have time to integrate it inside the framework.

//DatabaseSeeder.php
public function run(){
   $this->disableForeignKeyCheck();
   //....
   $this->enableForeignKeyCheck();
}

private function disableForeignKeyCheck(){
        $connection = config('database.connections')[config('database.default')];
        $sql='';
        switch ($connection['driver']) {
            case 'mysql':
                $sql='SET FOREIGN_KEY_CHECKS = 0';
                break;
            case 'sqlite':
                $sql='PRAGMA foreign_keys = OFF';
                break;
        }

        DB::statement($sql);
    }
    private function enableForeignKeyCheck(){
        $connection = config('database.connections')[config('database.default')];
        $sql='';
        switch ($connection['driver']) {
            case 'mysql':
                $sql='SET FOREIGN_KEY_CHECKS = 1';
                break;
            case 'sqlite':
                $sql='PRAGMA foreign_keys = ON';
                break;
        }

        DB::statement($sql);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants