我正在使用php脚本在Magento 1.7.0.2中创建新产品并更新现有产品。 这个脚本适用于单个或少数100个产品。如果创建或更新大量产品,比如5000,则会出现以下错误
SQLSTATE [23000]:完整性约束违规:1452无法添加或更新子行:外键约束失败(magento_live
。catalog_product_entity_varchar
,CONSTRAINT FK_CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID
FOREIGN KEY (entity_id
)参考catalog_product_entity
(entity_id
)D)
我使用的脚本,
const DEFAULT_STORE_ID=0;
const DEFAULT_VISIBILITY=4;
const DEFAULT_TAXCLASS=2;
/**
* @var Mage_Catalog_Model_Product
*/
protected $magentoProduct;
protected $errors=array();
public function __construct()
{
Mage::app()->setCurrentStore(0);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
Mage::getSingleton('core/session', array('name' => 'adminhtml'));
$userModel=Mage::getModel('admin/user');
$userModel->setUserId(1);
$session=Mage::getSingleton('admin/session');
$session->setUser($userModel);
$session->setAcl(Mage::getResourceModel('admin/acl')->loadAcl());
}
public function getErrors()
{
return $this->errors;
}
public function save($productData)
{
$start=microtime(true);
$this->magentoProduct=Mage::getModel('catalog/product');
$magentoProductId=$this->magentoProduct->getIdBySku($productData['sku']);
$this->magentoProduct->load($magentoProductId);
if (!$this->magentoProduct->getId())
{
mage::log("ADDING sku-" . $productData['sku']);
try
{
$this->magentoProduct->setWebsiteIds(array(1));
$this->magentoProduct->setAttributeSetId($this->magentoProduct->getDefaultAttributeSetId());
$this->magentoProduct->setStoreId(self::DEFAULT_STORE_ID);
$this->magentoProduct->setTypeId('simple');
$this->magentoProduct->setSku($productData['sku']);
$this->magentoProduct->setName($productData['name']);
$this->magentoProduct->setDescription($productData['description']);
$this->magentoProduct->setShortDescription($productData['short_description']);
$this->magentoProduct->setPrice(floatval($productData['price']));
$this->magentoProduct->setCost(floatval($productData['cost']));
$this->magentoProduct->setIsImported($productData['is_imported']);
$this->magentoProduct->setMfgpartno($productData['mfgpartno']);
$this->magentoProduct->setEtilizeProductId($productData['etilize_product_id']);
$this->magentoProduct->setCondition($productData['condition']);
$this->magentoProduct->setManufacturer($productData['manufacture']);
$this->magentoProduct->setCategoryIds($productData['category_id']); // need to look these up
$this->magentoProduct->setWeight($productData['weight']);
$this->magentoProduct->setTaxClassId(self::DEFAULT_TAXCLASS); // taxable goods
$this->magentoProduct->setVisibility(self::DEFAULT_VISIBILITY); // catalog, search
$this->magentoProduct->setStatus(intval($productData['status'])); // enabled
$this->magentoProduct->setCategoryIds($productData['category_id']);
$this->magentoProduct->save();
Mage::log("saving stock for new product");
$stockItem = Mage::getModel('cataloginventory/stock_item');
$stockItem->assignProduct($this->magentoProduct);
$qty = (integer)$productData['qty'];
$stockItem->setData('qty', $qty);
$stockItem->setData('is_in_stock', $qty > 0 ? 1:0);
$stockItem->setData('stock_id', $productData['stock_id']);
$stockItem->setData('manage_stock', 0);
$stockItem->save();
}
catch (Exception $e)
{
Mage::log("Failed Saving Product: " . $e->getMessage());
}
$magentoProductId=$this->magentoProduct->getId();
unset($this->magentoProduct);
}
else
{
mage::log("UPDATING sku-" . $productData['sku']);
try
{
$this->magentoProduct->setMfgpartno($productData['mfgpartno']);
$this->magentoProduct->setEtilizeProductId($productData['etilize_product_id']);
$this->magentoProduct->setCondition($productData['condition']);
$this->magentoProduct->setPrice(floatval($productData['price']));
$this->magentoProduct->setCost(floatval($productData['cost']));
$this->magentoProduct->setWeight($productData['weight']);
$this->magentoProduct->setTaxClassId($productData['tax_class_id']);
$this->magentoProduct->setManufacturer($productData['manufacture']);
$qty=(integer)$productData['qty'];
$inStock=($qty > 0) ? 1 : 0;
$stockData = $this->magentoProduct->getStockData();
$stockData['qty'] = $qty;
$stockData['is_in_stock'] = $inStock;
$stockData['manage_stock'] = 1;
$stockData['use_config_manage_stock'] = 0;
$this->magentoProduct->setStockData($stockData);
$this->magentoProduct->save();
}
catch (Exception $e)
{
Mage::log("Failed Update Product: " . $e->getMessage());
}
$magentoProductId=$this->magentoProduct->getId();
unset($this->magentoProduct);
}
return $magentoProductId;
}
此脚本放在Magneto自定义模块中,我在数据库表中有产品列表。我正在从此表中选择产品,并使用上述脚本更新或插入magento。该过程通过curl请求进行初始化。我还尝试将其插入100或50批次。在更新或插入约3000个产品后仍然会出现相同的错误。我还在运行流程之前将索引模式更改为手动。
任何帮助都会非常感激。谢谢!
答案 0 :(得分:1)
问题不在于因为重复输入而插入或更新了多少产品。所以不要插入重复的数据。 Magento数据库利用外键约束来确保数据库的完整性。例如,如果删除某个类别,则必须删除类别树中其下面的所有类别。
Cannot add or update a child row: a foreign key constraint fails
发生此错误是因为您要导入的数据是逐行提供的,而不考虑数据库的逻辑结构和完整性。
我在我的一个插入产品类别的项目中遇到了同样的问题,之后我使用了正确的检查功能来避免这种类型的错误。我的问题是我使用外部id作为类别,但有些情况下外部id与原始id不匹配。
您可以做一件事,使用Mage日志(您已经在使用)进行插入和更新,以检查您的导入停止的产品。如果您发现问题ID,则检查此特定ID的所有数据,并尝试仅使用代码导入/插入此特定数据。找出问题所在的数据并进行修复。如果我可以帮助你,请告诉我。
答案 1 :(得分:1)
暂时摆脱问题,你可以关闭mysql中的外键,但这当然没有正确的解决方案。我会检查是否在创建或更新产品时发生了崩溃。在创建的情况下,我会检查产品在保存新产品后是否具有ID,并且仅在存在此ID时才应用库存数据。一般来说要小心类别ID。希望这有点帮助!