I have two databases (com and usa) with a table with the following schema:
Create Table: CREATE TABLE `eav_attribute` (
`attribute_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Attribute Id',
`entity_type_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type Id',
`attribute_code` varchar(255) NOT NULL COMMENT 'Attribute Code',
PRIMARY KEY (`attribute_id`),
UNIQUE KEY `UNQ_EAV_ATTRIBUTE_ENTITY_TYPE_ID_ATTRIBUTE_CODE` (`entity_type_id`,`attribute_code`),
KEY `IDX_EAV_ATTRIBUTE_ENTITY_TYPE_ID` (`entity_type_id`),
CONSTRAINT `FK_EAV_ATTRIBUTE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID` FOREIGN KEY (`entity_type_id`) REFERENCES `eav_entity_type` (`entity_type_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=212 DEFAULT CHARSET=utf8 COMMENT='Eav Attribute'
1 row in set (0.00 sec)
I'd like to make the attribute_ids of USA the same as COM (where code + type match). This query shows my expected result by joining the two tables:
SELECT usa_attribute.attribute_id,
usa_attribute.entity_type_id,
usa_attribute.attribute_code,
com_attribute.attribute_id,
com_attribute.entity_type_id,
com_attribute.attribute_code
FROM eav_attribute usa_attribute
LEFT JOIN com.eav_attribute com_attribute
ON ( usa_attribute.entity_type_id = com_attribute.entity_type_id
AND usa_attribute.attribute_code = com_attribute.attribute_code );
+--------------+----------------+--------------------------------+--------------+----------------+--------------------------------+
| attribute_id | entity_type_id | attribute_code | attribute_id | entity_type_id | attribute_code |
+--------------+----------------+--------------------------------+--------------+----------------+--------------------------------+
| 615 | 1 | confirmation | 16 | 1 | confirmation |
| 616 | 1 | created_at | 481 | 1 | created_at |
| 602 | 1 | created_in | 3 | 1 | created_in |
| 612 | 1 | default_billing | 13 | 1 | default_billing |
| 613 | 1 | default_shipping | 14 | 1 | default_shipping |
| 782 | 1 | disable_auto_group_change | 571 | 1 | disable_auto_group_change |
| 610 | 1 | dob | 11 | 1 | dob |
| 647 | 3 | children | 46 | 3 | children |
| 656 | 3 | children_count | 55 | 3 | children_count |
| 706 | 3 | custom_apply_to_products | 494 | 3 | custom_apply_to_products |
| 649 | 3 | custom_design | 48 | 3 | custom_design |
| 651 | 3 | custom_design_from | 50 | 3 | custom_design_from |
| 652 | 3 | custom_design_to | 51 | 3 | custom_design_to |
| 654 | 3 | custom_layout_update | 53 | 3 | custom_layout_update |
| 705 | 3 | custom_use_parent_settings | 493 | 3 | custom_use_parent_settings |
| 658 | 3 | default_sort_by | 486 | 3 | default_sort_by |
| 635 | 3 | description | 34 | 3 | description |
| 640 | 3 | display_mode | 39 | 3 | display_mode |
| 707 | 3 | filter_price_range | 495 | 3 | filter_price_range |
| 636 | 3 | image | 35 | 3 | image |
| 704 | 3 | include_in_menu | 490 | 3 | include_in_menu |
| 633 | 3 | is_active | 32 | 3 | is_active |
| 642 | 3 | is_anchor | 41 | 3 | is_anchor |
| 810 | 3 | is_spacer | 599 | 3 | is_spacer |
| 641 | 3 | landing_page | 40 | 3 | landing_page |
| 655 | 3 | level | 54 | 3 | level |
| 639 | 3 | meta_description | 38 | 3 | meta_description |
| 638 | 3 | meta_keywords | 37 | 3 | meta_keywords |
| 637 | 3 | meta_title | 36 | 3 | meta_title |
| 632 | 3 | name | 31 | 3 | name |
| 653 | 3 | page_layout | 52 | 3 | page_layout |
| 643 | 3 | path | 42 | 3 | path |
| 646 | 3 | path_in_store | 45 | 3 | path_in_store |
| 644 | 3 | position | 43 | 3 | position |
| 719 | 3 | thumbnail | 568 | 3 | thumbnail |
| 634 | 3 | url_key | 33 | 3 | url_key |
| 648 | 3 | url_path | 47 | 3 | url_path |
| 679 | 4 | color | 76 | 4 | color |
| 772 | 4 | color_description | 469 | 4 | color_description |
| 667 | 4 | cost | 64 | 4 | cost |
| 788 | 4 | country_of_manufacture | 577 | 4 | country_of_manufacture |
| 702 | 4 | created_at | 488 | 4 | created_at |
| 691 | 4 | custom_design | 86 | 4 | custom_design |
| 692 | 4 | custom_design_from | 87 | 4 | custom_design_from |
| 693 | 4 | custom_design_to | 88 | 4 | custom_design_to |
| 694 | 4 | custom_layout_update | 89 | 4 | custom_layout_update |
| 660 | 4 | description | 57 | 4 | description |
| 740 | 4 | e3ac01 | 539 | 4 | e3ac01 |
| 741 | 4 | e3ac02 | 540 | 4 | e3ac02 |
| 742 | 4 | e3ac03 | 541 | 4 | e3ac03 |
| 743 | 4 | e3ac04 | 542 | 4 | e3ac04 |
| 744 | 4 | e3ac05 | 543 | 4 | e3ac05 |
| 745 | 4 | e3ac06 | 544 | 4 | e3ac06 |
| 746 | 4 | e3ac07 | 545 | 4 | e3ac07 |
| 747 | 4 | e3ac08 | 546 | 4 | e3ac08 |
| 748 | 4 | e3ac09 | 547 | 4 | e3ac09 |
| 730 | 4 | e3cdes | 456 | 4 | e3cdes |
| 735 | 4 | e3col | 461 | 4 | e3col |
| 725 | 4 | e3cono | 451 | 4 | e3cono |
| 749 | 4 | e3cost | 548 | 4 | e3cost |
| 731 | 4 | e3csds | 457 | 4 | e3csds |
| 758 | 4 | e3ris1 | 553 | 4 | e3ris1 |
+--------------+----------------+--------------------------------+--------------+----------------+--------------------------------+
Before I run the query I can confirm that USA has no attribute_id = 51:
# There is no attribute_id before I begin the copy
mysql> select * from eav_attribute where attribute_id = 51;
Empty set (0.00 sec)
However the update causes a FK constraint error. Any idea why? How do I do this update successfully?
UPDATE eav_attribute usa_attribute,
com.eav_attribute com_attribute
SET usa_attribute.attribute_id = com_attribute.attribute_id
WHERE usa_attribute.entity_type_id = com_attribute.entity_type_id
AND usa_attribute.attribute_code = com_attribute.attribute_code
Upholding foreign key constraints for table 'eav_attribute', entry '51', key 1 would lead to a duplicate entry
Best Answer
Ok, so I should have guessed - when getting a FK error I should check other tables referencing this table to see if ON UPDATE CASCADE might cause issues. To do this I did the following query:
I was then able to do a quick select against these tables:
Then I could see that two tables had references to my first table (eav_attribute) with the values '51'.
Not sure how these got there, but since they dont match the FK I could happily delete them.