商品属性文字批量更新
Mass update of product attribute text
我工作的前任开发人员为所有产品分配了一个名为 "delivery_text" 的属性,其中包含 html 的字符串。对于每个产品,此字符串的主体都是唯一的。但是,每个都包含一个 link 到特定的 url(每个产品的 link 都相同)。由于我们网站布局的变化,我们现在需要为每个产品更新这个 link,而不影响属性文本的其余部分。
显然,我不想为了更改每个产品 delivery_text 字符串中 link 的 url 而手动编辑数千个产品。
有没有一种方法可以以编程方式为每个产品解析此属性的内容,并将 links 的实例替换为 oldsite.com/old-url ,将 links 替换为 newsite.com/new-url ?
我想我可以通过某种数据库技巧来做到这一点,并且可以通过 cpan 访问 phpmyadmin,但我不知道如何真正去做。
请注意,我不认为这是一个重复的问题,因为虽然有很多 "how do i mass update attribute values for all products" 类型的问题,但我还没有找到一个问 "how do i search and replace a specific character sequence within the attribute text for each product" 的问题。
如果您想从数据库中执行此操作,您可以这样做:
查找属性值
SELECT at.* FROM catalog_product_entity_varchar AS at
INNER JOIN eav_attribute AS ea
ON ea.attribute_id = at.attribute_id
WHERE ea.attribute_code = 'delivery_text';
这应该会显示当前数据库中所有属性值的列表。
更新属性值
找到所有值后,您可以使用相同的查询来替换值中的 URL:
UPDATE catalog_product_entity_varchar AS at
INNER JOIN eav_attribute AS ea
ON ea.attribute_id = at.attribute_id
SET at.value = REPLACE(at.value, 'http://oldurl.com', 'http://newurl.com')
WHERE ea.attribute_code = 'delivery_text';
没有SQL
您也可以使用 Magento 模型 API 执行此操作。首先收集您需要的数据,方法同上:
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('delivery_text');
foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
var_dump($product->getDeliveryText());
}
然后您可以更新循环中的属性。在这里您需要指定一个商店 ID,所以我假设您将在管理(全局)范围内执行此操作:
$old = 'http://oldurl.com';
$new = 'http://newurl.com';
foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
Mage::getModel('catalog/product_action')
->updateAttributes(
array($product->getId()),
array('delivery_text' => $new),
Mage_Core_Model_App::ADMIN_STORE_ID
);
}
请注意: 使用 Mage_Catalog_Model_Product_Action::updateAttributes
可以快速有效地更新给定商店级别的产品属性,但如果您没有使用管理商店级别,则you may not be able to retrieve the value in a collection 因为此方法不会创建默认值 - 它只是按照它所说的去做; create/update 给定商店级别的值。
我工作的前任开发人员为所有产品分配了一个名为 "delivery_text" 的属性,其中包含 html 的字符串。对于每个产品,此字符串的主体都是唯一的。但是,每个都包含一个 link 到特定的 url(每个产品的 link 都相同)。由于我们网站布局的变化,我们现在需要为每个产品更新这个 link,而不影响属性文本的其余部分。
显然,我不想为了更改每个产品 delivery_text 字符串中 link 的 url 而手动编辑数千个产品。 有没有一种方法可以以编程方式为每个产品解析此属性的内容,并将 links 的实例替换为 oldsite.com/old-url ,将 links 替换为 newsite.com/new-url ?
我想我可以通过某种数据库技巧来做到这一点,并且可以通过 cpan 访问 phpmyadmin,但我不知道如何真正去做。
请注意,我不认为这是一个重复的问题,因为虽然有很多 "how do i mass update attribute values for all products" 类型的问题,但我还没有找到一个问 "how do i search and replace a specific character sequence within the attribute text for each product" 的问题。
如果您想从数据库中执行此操作,您可以这样做:
查找属性值
SELECT at.* FROM catalog_product_entity_varchar AS at
INNER JOIN eav_attribute AS ea
ON ea.attribute_id = at.attribute_id
WHERE ea.attribute_code = 'delivery_text';
这应该会显示当前数据库中所有属性值的列表。
更新属性值
找到所有值后,您可以使用相同的查询来替换值中的 URL:
UPDATE catalog_product_entity_varchar AS at
INNER JOIN eav_attribute AS ea
ON ea.attribute_id = at.attribute_id
SET at.value = REPLACE(at.value, 'http://oldurl.com', 'http://newurl.com')
WHERE ea.attribute_code = 'delivery_text';
没有SQL
您也可以使用 Magento 模型 API 执行此操作。首先收集您需要的数据,方法同上:
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('delivery_text');
foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
var_dump($product->getDeliveryText());
}
然后您可以更新循环中的属性。在这里您需要指定一个商店 ID,所以我假设您将在管理(全局)范围内执行此操作:
$old = 'http://oldurl.com';
$new = 'http://newurl.com';
foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
Mage::getModel('catalog/product_action')
->updateAttributes(
array($product->getId()),
array('delivery_text' => $new),
Mage_Core_Model_App::ADMIN_STORE_ID
);
}
请注意: 使用 Mage_Catalog_Model_Product_Action::updateAttributes
可以快速有效地更新给定商店级别的产品属性,但如果您没有使用管理商店级别,则you may not be able to retrieve the value in a collection 因为此方法不会创建默认值 - 它只是按照它所说的去做; create/update 给定商店级别的值。