You exported a database from your old host, opened phpMyAdmin on your Getwebup cPanel account, hit Import, and got a wall of red text instead of a finished job. If the error mentions "foreign key constraint" or an error number like #1005 or #1452, you're not looking at a corrupt file — you're looking at tables that got imported in the wrong order, or a mismatch phpMyAdmin can't paper over. Here's what's actually going on and how to get the import through cleanly.
Symptom: What the Error Actually Looks Like
You'll usually see one of these, either in the phpMyAdmin error banner or partway down a long SQL file:
#1005 - Can't create table 'db_name.wp_postmeta' (errno: 150 "Foreign key constraint is incorrectly formed")#1452 - Cannot add or update a child row: a foreign key constraint fails#1451 - Cannot delete or update a parent row: a foreign key constraint fails- Import stops midway, phpMyAdmin shows a partial success, and some tables are simply missing afterward
The common thread: MySQL is refusing to create a table, insert a row, or drop a row because a foreign key relationship doesn't hold up at that exact moment in the import.
Cause: Why This Happens on a Perfectly Good Export
None of this means your data is broken. It almost always comes down to one of these:
1. Table creation order
A .sql dump creates tables in the order they appear in the file. If orders_items (which has a foreign key to orders) is defined before orders exists yet, MySQL rejects the CREATE TABLE statement outright. This is common with hand-trimmed exports or files stitched together from multiple sources.
2. FK checks are still on during import
By default MySQL enforces foreign keys as each statement runs. A clean mysqldump wraps the whole file in SET FOREIGN_KEY_CHECKS=0 so order doesn't matter — but not every export tool does this, and some GUI database managers strip that line out when they "clean up" the file.
3. Storage engine mismatch
Foreign keys only work between InnoDB tables. If one table got converted to MyISAM at some point — often from an old "optimize tables" pass in an admin panel — any FK referencing it will fail with errno 150, and the message won't mention MyISAM anywhere.
4. Charset or collation mismatch on the key columns
A foreign key column and the parent's primary key column must match in data type and collation. utf8_general_ci vs utf8mb4_unicode_ci on what looks like "the same" varchar(20) column is enough to make MySQL treat them as incompatible.
5. Orphaned data (the real one to worry about)
Sometimes the constraint is correctly formed and the real problem is the data: a row in the child table points to a parent row that no longer exists. This usually traces back to a bad manual delete on the old server, and disabling checks just imports the orphan instead of fixing anything.
Fix: Getting the Import Through
Step 1 — Disable FK checks for the import (safe for order/table-order issues)
In cPanel, open Databases > phpMyAdmin, select the target database, and before importing, open the .sql file in a text editor and add these two lines:
SET FOREIGN_KEY_CHECKS=0;
-- ... your existing dump content stays here ...
SET FOREIGN_KEY_CHECKS=1;Put the first line at the very top of the file and the second at the very bottom, then re-upload it in phpMyAdmin's Import tab. This tells MySQL to skip the ordering/reference check while tables are being created and only verify everything once the whole file has loaded.
If the file is too large for phpMyAdmin's upload limit (see upload_max_filesize in cPanel's MultiPHP INI Editor), do the same thing over SSH instead, which skips the web upload limit entirely:
mysql -u your_db_user -p your_database_name -e "SET FOREIGN_KEY_CHECKS=0; SOURCE /home/username/dump.sql; SET FOREIGN_KEY_CHECKS=1;"Step 2 — Fix an engine mismatch
If disabling checks doesn't help, or the error names a specific table, check its engine:
SHOW TABLE STATUS WHERE Name = 'orders_items';If Engine shows MyISAM instead of InnoDB, convert it before re-importing:
ALTER TABLE orders_items ENGINE=InnoDB;Step 3 — Fix a collation mismatch
Compare the parent and child key columns:
SHOW CREATE TABLE orders;
SHOW CREATE TABLE orders_items;Look at the collation on the referenced columns specifically (not just the table default). If they differ, align the child to the parent:
ALTER TABLE orders_items MODIFY order_id VARCHAR(20) COLLATE utf8mb4_unicode_ci;Step 4 — Find and handle real orphaned rows
Before you blame the schema, rule out bad data. This finds child rows with no matching parent:
SELECT oi.* FROM orders_items oi
LEFT JOIN orders o ON oi.order_id = o.id
WHERE o.id IS NULL;If that returns rows, you have a genuine orphan problem, not a formatting one. Decide per case whether to delete the orphaned rows, or recreate the missing parent record if you know what it should contain — don't just force the constraint off and leave it, or the same query will keep returning results after every future export.
If phpMyAdmin says "Missing expression. (near "ON" at position 25)"
That one is not a MySQL error. Before phpMyAdmin sends your SQL to the server, it runs it through its own checker and prints what it finds as Static analysis: 1 errors were found during analysis. That checker misreads one common line:
SET FOREIGN_KEY_CHECKS = ON;Count the characters: SET FOREIGN_KEY_CHECKS = is exactly 25 long, so position 25 is where ON starts. MySQL itself accepts ON for this setting. phpMyAdmin's checker doesn't. Write it as a number instead, which every tool reads the same way:
SET FOREIGN_KEY_CHECKS = 0;
-- ... your import ...
SET FOREIGN_KEY_CHECKS = 1;If MySQL printed an error under the static-analysis message (#1452, #1005, or "MySQL server has gone away"), that second message is the real problem. Use the table below. "Server has gone away" on a large file usually means the dump is too big for a browser upload. Import it over SSH with the mysql command from Step 1.
Quick Reference: Error Message to Likely Cause
| Error | Most Likely Cause | First Thing to Check |
|---|---|---|
| #1005, errno: 150 | Table creation order, or engine mismatch | SHOW TABLE STATUS for the named table's engine |
| #1005, errno: 121 | Duplicate foreign key constraint name | Search the dump file for the same CONSTRAINT name used twice |
| #1452 (child row) | Orphaned data, or FK checks enabled mid-import | Run the LEFT JOIN orphan-check query above |
| #1451 (parent row) | Trying to delete a parent that still has children | Delete or reassign child rows first, or cascade the delete |
| Missing expression. (near "ON" at position 25) | Not a MySQL error: phpMyAdmin's own checker misreading SET FOREIGN_KEY_CHECKS = ON; | Write it as = 0 / = 1, then read the MySQL error under it, if any |
Prevention: Export It Right the First Time
- Export with
mysqldumpdirectly instead of a GUI tool where possible — it includesFOREIGN_KEY_CHECKS=0automatically:mysqldump -u user -p --single-transaction --routines --triggers database_name > dump.sql - Keep every table in a database on the same storage engine unless you have a specific reason not to — mixed InnoDB/MyISAM is the single biggest source of this error on older WordPress and WooCommerce databases.
- If you're migrating between hosts, export and import in one sitting rather than editing the dump file by hand in between — manual edits are where stray semicolons and dropped
SETstatements creep in. - After a successful import, run
CHECK TABLEon the key tables before you point the site live, so you catch a silent partial import before customers do.
If you're on a Getwebup VPS or reseller plan and the dump is large enough that phpMyAdmin keeps timing out regardless, our support team can run the import over SSH on our end — that's usually faster than fighting upload limits through the browser.