Magento如何管理外键约束

时间:2014-03-23 12:22:05

标签: mysql magento upgrade

我最近升级到法师1.8.1。似乎一切都很好,但重新指数产品价格。发现以下错误:

#1452 - Cannot add or update a child row: a foreign key constraint fails (`threeleavednew`.`catalog_product_index_tier_price`, CONSTRAINT `FK_CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_id)

这个数据库在升级之前由phpMyadmin导出并导入到一个新的空数据库(在我的域名托管下创建)。我刚刚提取了mage 1.8.1.tar.gz并复制了我的主题,并通过修改local.xml(保持加密密钥不变)将Mage 1.8指向新数据库,将mage 1.8目录重命名为httpdocs并启动我的网站....

  1. 我不确定这种升级方式是否会导致任何数据库外键问题。
  2. 我的旧网站是从其他开发者转移的,我不确定数据库是否从第一天开始出现FK问题,这可能与版本1.8不兼容。
  3. 我所做的是

    1)在phpMyadmin中使用以下语句

    select *
    from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    where CONSTRAINT_TYPE = 'FOREIGN KEY';
    

    从旧DB,当前DB和Mage示例DB转储所有外键。比较。

    2)在phpMyadmin中运行export to dump current DB和Mage sample DB,与升级前导出的旧DB进行比较。

    以下是结果。

    1)在Mage示例DB外键表中我可以找到catalog_product_index_tier_price表的三个FK键,如下所示

    'FK_CAT_PRD_IDX_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID',
    'FK_CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID', 
    'FK_CAT_PRD_IDX_TIER_PRICE_WS_ID_CORE_WS_WS_ID', 
    

    和一个FK,每个用于catalog_product_flat_1,_2,_3表。

    'FK_CAT_PRD_FLAT_1_ENTT_ID_CAT_PRD_ENTT_ENTT_ID',
    'FK_CAT_PRD_FLAT_2_ENTT_ID_CAT_PRD_ENTT_ENTT_ID', 
    'FK_CAT_PRD_FLAT_3_ENTT_ID_CAT_PRD_ENTT_ENTT_ID',
    

    但是,当我尝试在不同的时间从旧DB和当前DB转储FK表时,我有时会找到catalog_product_index_tier_price表的三个FK,有时我根本找不到它们,有时候发现FK名称就像' FK_6E08D719F0501DD1D8E6D4EFF2511C85&#39 ;.而且我从来没有为catalog_product_flat_1,_2,_3表找到任何FK。

    2)在旧的DB和当前数据库导出的.sql文件中,我没有找到任何这样的语句来为表catalog_product_index_tier_price和catalog_product_flat_1,_2,_3添加FK,但我在Mage的导出的.sql文件中找到它们样本数据库。

    ALTER TABLE `catalog_product_index_tier_price`
    ADD CONSTRAINT `FK_CAT_PRD_IDX_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID` FOREIGN KEY (`customer_group_id`) REFERENCES `customer_group` (`customer_group_id`) ON DELETE CASCADE ON UPDATE CASCADE,
    ADD CONSTRAINT `FK_CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE,
    ADD CONSTRAINT `FK_CAT_PRD_IDX_TIER_PRICE_WS_ID_CORE_WS_WS_ID` FOREIGN KEY (`website_id`) REFERENCES `core_website` (`website_id`) ON DELETE CASCADE ON UPDATE CASCADE;
    

    ALTER TABLE `catalog_product_flat_1`
    ADD CONSTRAINT `FK_CAT_PRD_FLAT_1_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE;
    

    好吧,看起来我的旧数据库和当前数据库都出现了FK问题并且出现了不稳定的症状。很明显,我的所有历史数据库备份文件都没有为这些表添加FK的语句,其中一个我曾用于导入数据库运行数据库运行数据库,我遇到了问题。我无法检查我的问题是由错误的升级方式引起的,或者从第一天起就可能存在。

    我的问题是

    1. Mage 1.8管理DB的方式与以前的版本不同吗?即使我不这么认为。
    2. Magento如何实际管理FK约束?它是否在最开始时分配FK约束名称和关系并保持所有这些名称和关系不变,或者它是否与销售或客户变更动态分配/重新分配FK约束名称和关系?我的理解是FK约束名称和关系永远不会改变,它的数据随站点运行而变化。
    3. 为什么phpMyadmin导出函数会转储数据库备份(甚至在网站工作正常时升级之前)更少"添加约束"声明比Mage示例DB上的相同转储?这是否意味着我的DB从第一天起就有错误/问题FK?如果是的话,为什么我升级到1.8后才遇到问题?
    4. 假设Magento静态管理FK,是否有标准/参考Magento FK约束列表,我们可以将其与我们的问题进行比较,以便进行简单的数据库调试?
    5. 我真的迷路了,希望有人能帮助我解决这些问题。先感谢您。 我看到很多法师FK错误线程都在谷歌搜索类似于我的,他们没有给我一个合理和合理的解决方案和解释。我期待一个解决方案,我可以看到为什么以及如何解决问题,而不仅仅是告诉我"截断一些表格,你将解决问题" ....

      非常感谢。

      更新:我试图跟踪查询流程并找到一些信息,希望主人知道问题出在哪里。

      ## 17493 ## TRANSACTION BEGIN
      TIME: 0.0001
      ## 2014-03-28 18:00:03
      ## 17493 ## QUERY
      SQL: DELETE FROM `catalog_product_index_price_idx`
      AFF: 410
      TIME: 0.0055
      ## 2014-03-28 18:00:03
      ## 17493 ## QUERY
      SQL: SELECT `cw`.`website_id`, `csg`.`default_store_id` AS `store_id` FROM `core_website` AS `cw`
      INNER JOIN `core_store_group` AS `csg` ON cw.default_group_id = csg.group_id WHERE  (cw.website_id != 0)
      AFF: 1
      TIME: 0.0006
      ## 2014-03-28 18:00:03
      ## 17493 ## QUERY
      SQL: DELETE FROM `catalog_product_index_website`
      AFF: 1
      TIME: 0.0003
      ## 2014-03-28 18:00:03
      ## 17493 ## QUERY
      SQL: INSERT INTO `catalog_product_index_website` (`website_id`,`website_date`,`rate`) VALUES  (?, ?, ?)
      BIND: array (  0 => '1',  1 => '2014-03-29',  2 => 1,)
      AFF: 1
      TIME: 0.0002
      ## 2014-03-28 18:00:03
      ## 17493 ## QUERY
      SQL: DELETE FROM `catalog_product_index_tier_price`
      AFF: 0
      TIME: 0.0002
      ## 2014-03-28 18:00:03
      ## 17493 ## QUERY
      SQL: DESCRIBE `catalog_product_index_tier_price`
      AFF: 4
      TIME: 0.0005
      
      ## 2014-03-28 18:00:03
      ## 17493 ## QUERY
      SQL: INSERT INTO `catalog_product_index_tier_price` SELECT `tp`.`entity_id`, `cg`.`customer_group_id`, `cw`.`website_id`, MIN(IF(tp.website_id = 0, ROUND(tp.value * cwd.rate, 4), tp.value)) FROM `catalog_product_entity_tier_price` AS `tp`
      INNER JOIN `customer_group` AS `cg` ON tp.all_groups = 1 OR (tp.all_groups = 0 AND tp.customer_group_id = cg.customer_group_id)
      INNER JOIN `core_website` AS `cw` ON tp.website_id = 0 OR tp.website_id = cw.website_id
      INNER JOIN `catalog_product_index_website` AS `cwd` ON cw.website_id = cwd.website_id WHERE (cw.website_id != 0) GROUP BY `tp`.`entity_id`,
      `cg`.`customer_group_id`,
      `cw`.`website_id` ON DUPLICATE KEY UPDATE `min_price` = VALUES(`min_price`)
      TIME: 0.0069
      
          ## 2014-03-28 18:00:03
          EXCEPTION 
          exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1452  Cannot add or update a child row: a foreign key constraint fails (`threeleavednew`.`catalog_product_index_tier_price`, CONSTRAINT `FK_CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_)' in /var/www/vhosts/3leavedcart.com/httpdocs/lib/Zend/Db/Statement/Pdo.php:228
          Stack trace:
          #0 /var/www/vhosts/3leavedcart.com/httpdocs/lib/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array)
          #1 /var/www/vhosts/3leavedcart.com/httpdocs/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
          #2 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Zend/Db/Statement.php(291): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
          #3 /var/www/vhosts/3leavedcart.com/httpdocs/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
          #4 /var/www/vhosts/3leavedcart.com/httpdocs/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('INSERT INTO `ca...', Array)
          #5 /var/www/vhosts/3leavedcart.com/httpdocs/lib/Varien/Db/Adapter/Pdo/Mysql.php(428): Zend_Db_Adapter_Pdo_Abstract->query('INSERT INTO `ca...', Array)
      #6 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Catalog/Model/Resource/Product/Indexer    /Price.php(455): Varien_Db_Adapter_Pdo_Mysql->query('INSERT INTO `ca...')
      #7 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Catalog/Model/Resource/Product/Indexer    /Price.php(379): Mage_Catalog_Model_Resource_Product_Indexer_Price->_prepareTierPriceIndex()
          #8 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Index/Model/Indexer/Abstract.php(143): Mage_Catalog_Model_Resource_Product_Indexer_Price->reindexAll()
          #9 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Index/Model/Process.php(210): Mage_Index_Model_Indexer_Abstract->reindexAll()
          #10 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Catalog/Model/Observer.php(203): Mage_Index_Model_Process->reindexAll()
          #11 [internal function]: Mage_Catalog_Model_Observer->reindexProductPrices(Object(Mage_Cron_Model_Schedule))
          #12 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Cron/Model/Observer.php(325): call_user_func_array(Array, Array)
          #13 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Cron/Model/Observer.php(72): Mage_Cron_Model_Observer->_processJob(Object(Mage_Cron_Model_Schedule), Object(Mage_Core_Model_Config_Element))
          #14 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Core/Model/App.php(1338): Mage_Cron_Model_Observer->dispatch(Object(Varien_Event_Observer))
          #15 /var/www/vhosts/3leavedcart.com/httpdocs/app/code/core/Mage/Core/Model/App.php(1317): Mage_Core_Model_App->_callObserverMethod(Object(Mage_Cron_Model_Observer), 'dispatch', Object(Varien_Event_Observer))
          #16 /var/www/vhosts/3leavedcart.com/httpdocs/app/Mage.php(448): Mage_Core_Model_App->dispatchEvent('default', Array)
          #17 /var/www/vhosts/3leavedcart.com/httpdocs/cron.php(76): Mage::dispatchEvent('default')
          #18 {main}
      

      以下只能在mysqld.log文件中找到

      140319 16:41:21  InnoDB: Error: in ALTER TABLE `threeleavednew`.`catalog_product_index_tier_price`
      InnoDB: has or is referenced in foreign key constraints
      InnoDB: which are not compatible with the new table definition.
      

      我还比较了我的DB中的表catalog_product_index_tier_price和Mage示例DB中的表结构和相关约束名称+关系...实际上,我比较了10个我怀疑的表,没有任何线索。

      谢谢。

2 个答案:

答案 0 :(得分:1)

我认为你有点过于复杂。 Magento具有安装时设置的FK约束。我认为可能发生的是你的Magento的数据库结构在整个过程中被破坏了,最近你升级到了1.8 - 这些表得到了修饰,当它们被修饰时,FK约束被重置为它们应该是什么。

长话短说,你可能有一个不好的扩展,或者你可能想看看可能导致你的数据库结构损坏的原因。自刚升级以来,新结构更有可能是合适的。

最后请注意:价格指数的好处在于,您可以截断表并重新应用索引而不会产生任何后果。我建议你这样做,看看它是否有帮助。

答案 1 :(得分:0)

时间在流逝,所以当我第一次回复罗恩时,我决定采用我头脑中的古老方法...它花了我半天多的时间,但比花费几天时间尝试其他方法更好希望...我不确定这是否可以成为那些在社区中遇到类似错误的人的最终解决方案,以防万一有人搜索这个帖子。

以下是我的所作所为,之后,只要您愿意,重新索引产品价格和标签将是小菜一碟。

  1. 转储您的数据库并使用编辑器打开它,找到指向' catalog_product_entity.entity_id'的所有FK关系。这是父表,记下子表。其中大多数是以目录或标签等开始的。
  2. 打开你的phpMyAdmin或类似工具,使用下面的语句在Fk' entity_id'中查找这些子表中的所有行。或者' product_id'引用" catalog_product_entity.entity_id'但不再存在于父表中并将其全部删除。

    SELECT * FROM child table name WHERE ' PRODUCT_ID'或者' enitty_id'不在(选择' entity_id' from' catalog_product_entity');

  3. 只删除您在此语句中找到的行,并将其余行留在那里。

  4. 您可能需要在一张桌子旁边执行此操作,有些FK是' product_id'有些是' enitty_id',所以要小心...我的数据库有一些产品被删除之前不在' catalog_product_entity'我们不再使用表格了,但是他们的旧实体_id'仍然存在于许多其他表中,与“目录_产品实体”有关系。表。我所做的是找出那些行并从子表中删除它们。删除phpMyadmin中的表行非常简单。

    就是这样,去清除var / cache和var / locks,登录beckend admin来做reindex并查看所有绿色!

    这个问题的先决条件是Magento的所有FK约束(名称和关系)都被定义一次并且保持不变......这就是我被问到的并且在开始时不确定。