Skip to content

Instantly share code, notes, and snippets.

@molotovbliss
Last active March 9, 2021 14:08
Show Gist options
  • Save molotovbliss/7c6eb4e661663f55526d6d4ec0408f65 to your computer and use it in GitHub Desktop.
Save molotovbliss/7c6eb4e661663f55526d6d4ec0408f65 to your computer and use it in GitHub Desktop.
Magento version 1 & 2, Locate Orphaned Records by Foreign Keys, and display SQL to Remove them.
<?php
// USE WITH MAGENTO 2.X
// Edit function call with DB details
// Usage: php removeOrphanFKs.php
// Used in conjunction with Magento Data Migration Tool
//
// Original script from: David Grudl (https://github.com/dg/MySQL-check)
// Modified by: Jared Blalock (http://molotovbliss.com)
//
// Adjust include for env.php and execute:
// php -f removeOrphanFks-m2.php
$config = include_once("../app/etc/env.php");
$dbConfig = $config['db']['connection']['default'];
$host = $dbConfig['host'];
$user = $dbConfig['username'];
$pass = $dbConfig['password'];
$db = $dbConfig['dbname'];
// Locate Orphan Foreign Keys, echo the DELETE SQL Query and execute it
function checkForeignKeys(mysqli $db, $database = NULL)
{
// get a list off all foreign keys from schema
$keys = $db->query('SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL' . ($database ? " AND TABLE_SCHEMA='{$db->escape_string($database)}'" : ''));
try {
// loop over all fk
foreach ($keys as $key) {
foreach ($key as & $identifier) {
$identifier = '`' . str_replace('`', '``', $identifier) . '`';
}
// detect orphans
$sqlQuery = "SELECT COUNT($key[COLUMN_NAME]) FROM $key[TABLE_SCHEMA].$key[TABLE_NAME] WHERE $key[COLUMN_NAME] NOT IN (SELECT $key[REFERENCED_COLUMN_NAME] FROM $key[TABLE_SCHEMA].$key[REFERENCED_TABLE_NAME])";
$row = @$db->query($sqlQuery)->fetch_array();
if(is_array($row) && $row[0] >= 1) {
echo $row[0] ? "-- $key[TABLE_SCHEMA] $key[TABLE_NAME].$key[COLUMN_NAME]: found $row[0] invalid foreign keys!".PHP_EOL : "";
// orphans found remove them
if($row[0]) {
//$delQuery = "DELETE FROM $key[TABLE_SCHEMA].$key[TABLE_NAME] WHERE $key[COLUMN_NAME] NOT IN (SELECT $key[REFERENCED_COLUMN_NAME] FROM $key[TABLE_SCHEMA].$key[REFERENCED_TABLE_NAME])";
$delQuery = "DELETE FROM $key[TABLE_NAME] WHERE $key[COLUMN_NAME] NOT IN (SELECT $key[REFERENCED_COLUMN_NAME] FROM $key[REFERENCED_TABLE_NAME])";
echo $delQuery . PHP_EOL . PHP_EOL;
//$db->query($delQuery); // uncomment out if you'd like to execute
}
}
}
} catch (Exception $e) {
print_r($e);
}
}
checkForeignKeys(new mysqli($host, $user, $pass), $db);
<?php
// USE WITH MAGENTO 1.X
// Edit function call with DB details
// Usage: php removeOrphanFKs.php
// Used in conjunction with Magento Data Migration Tool
//
// Original script from: David Grudl (https://github.com/dg/MySQL-check)
// Modified by: Jared Blalock (http://molotovbliss.com)
//
// Adjust DB details and execute:
// php -f removeOrphanFKs.php
$host = 'localhost';
$user = 'root';
$pass = 'password';
$db = 'dbname';
// Locate Orphan Foreign Keys, echo the DELETE SQL Query and execute it
function checkForeignKeys(mysqli $db, $database = NULL)
{
// get a list off all foreign keys from schema
$keys = $db->query('SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL' . ($database ? " AND TABLE_SCHEMA='{$db->escape_string($database)}'" : ''));
// loop over all fk
foreach ($keys as $key) {
foreach ($key as & $identifier) {
$identifier = '`' . str_replace('`', '``', $identifier) . '`';
}
// detect orphans
$sqlQuery = "SELECT COUNT($key[COLUMN_NAME]) FROM $key[TABLE_SCHEMA].$key[TABLE_NAME] WHERE $key[COLUMN_NAME] NOT IN (SELECT $key[REFERENCED_COLUMN_NAME] FROM $key[TABLE_SCHEMA].$key[REFERENCED_TABLE_NAME])";
$row = $db->query($sqlQuery)->fetch_array();
echo $row[0] ? "$key[TABLE_SCHEMA] $key[TABLE_NAME].$key[COLUMN_NAME]: found $row[0] invalid foreign keys!\n" : "";
// orphans found remove them
if($row[0]) {
$delQuery = "DELETE FROM $key[TABLE_SCHEMA].$key[TABLE_NAME] WHERE $key[COLUMN_NAME] NOT IN (SELECT $key[REFERENCED_COLUMN_NAME] FROM $key[TABLE_SCHEMA].$key[REFERENCED_TABLE_NAME])";
echo $delQuery;
//$db->query($delQuery); // uncomment out if you'd like to execute
}
}
}
checkForeignKeys(new mysqli($host, $user, $pass), $db);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment