Самый быстрый способ обновить атрибут во всех продуктах


14

Я пытаюсь обновить цену для многих продуктов (более 10.000). То, как я это делаю сейчас, очень трудоемко. Какой лучший способ просмотреть все продукты и обновить большинство из них?

Благодарность


Ответы:


22

Привет Magento предоставить атрибут с помощью кода ниже

$product->setAttributeCode($newValue)
$ProductObject->getResource()->saveAttribute($product, 'attribute_Code');

Пример:

$product=Mage::getModel('catalog/product')->load($id);
$product->setSpecialFromDate('2010-10-28');
// below code use for time format 
$product->setSpecialFromDateIsFormated(true);
$product->getResource()->saveAttribute($product, 'special_from_date');

Использование коллекции продуктов:

$productIds = array(1,3,2);
$products = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', array('in' => $productIds));

foreach($products as $product)
{
    $product->setSpecialFromDate('2010-10-28');
    // below code use for time format 
    $product->setSpecialFromDateIsFormated(true);
    $product->getResource()->saveAttribute($product, 'special_from_date');


}

Это супер быстро! Я пробовал Mage::getSingleton('catalog/product_api')->update();и Mage::getSingleton('catalog/product_action')->updateAttributes(). product_api занял 1,7 секунды в среднем, а product_action - 1,0 секунды в среднем. Тем не менее, $product->getResource()->saveAttribute()взял на 0,04 секунды в среднем. Благодарность!
Джошуа Пак

Есть ли что-то похожее на этот метод, который может обновлять атрибуты на определенном уровне магазина?
Робби Аверилл

Thx @Amit Bera - осталось 1 вопрос;) есть ли способ сохранить несколько атрибутов за один раз? Один должен был бы обойти вокруг $product->getResource()->saveAttributeдействия. СПАСИБО!!
snh_nl

@amit bera, пожалуйста, посмотрите на этот magento.stackexchange.com/questions/201757/… что мне делать ??
Абхишек

@amit: мне нужно, как я могу массово изменить сайт (обновить атрибут в мульти-магазине)
zus

18

Написать запрос SQL.

Второй лучший способ (и тот, который я рекомендую): \Mage_Catalog_Model_Resource_Product_Action::updateAttributes

Пример кода от u_maxx:

$allProductIds = Mage::getModel('catalog/product')->getCollection()->getAllIds();
$attributeCode = 'some_eav_attribute';
$attributeValue = NULL;
$attrData = array( $attributeCode => $attributeValue );
$storeId = 0;
// no reindex:<
Mage::getSingleton('catalog/resource_product_action')->updateAttributes($allPro‌​ductIds, $attrData, $storeId);
// reindex:
Mage::getModel('catalog/product_action')->updateAttributes($allPro‌​ductIds, $attrData, $storeId);

Как это будет работать с множественными значениями? Добавляет ли оно значение или перезаписывает другие предварительно выбранные значения?

Мультиселекты обычно сохраняются как целые числа, разделенные запятыми, например 27,42,4711. Поэтому, если вы измените значение, чтобы сказать 1, другие значения будут потеряны. Но то, что вы можете сделать, это что-то вроде CONCAT(value, ',1')средства добавления нового значения в конец, разделенного запятой. Я думаю, что даже если вы добавите значение два раза, это не проблема, потому что Magento фильтрует его при следующем сохранении элемента и игнорирует второе значение.


Это будет обновлять только 1 тыс. Строк за раз, но не так быстро: github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/…
B00MER

Когда я правильно понимаю код, он записывает каждые 1000 строк, но обновляет все подряд.
Фабиан Блехшмидт

1
Спасибо @FabianBlechschmidt! Вот мой пример кода ( суть ):<?php $allProductIds = Mage::getModel('catalog/product')->getCollection()->getAllIds(); $attributeCode = 'some_eav_attribute'; $attributeValue = NULL; $attrData = array( $attributeCode => $attributeValue ); $storeId = 0; Mage::getSingleton('catalog/resource_product_action')->updateAttributes($allProductIds, $attrData, $storeId);
Макс Урода

1
Проблема этого подхода заключается в том, что он не переиндексирует продукты, поэтому вы можете не видеть изменений во внешнем интерфейсе, а просто видеть их в панели администратора. Чтобы также переиндексировать после обновления, вы можете перейти Mage::getSingleton('catalog/resource_product_action')на Mage::getModel('catalog/product_action')те же параметры, что указаны выше.
шампунь

1
@snh_nl обновил ответ. Надеюсь, что это отвечает на ваш вопрос
Фабиан Blechschmidt

5

10 тыс. Продуктов, используйте SQL. EAV просто мутит воду. За вопрос самый быстрый способ.

Найти attribute_id

SELECT * FROM eav_attribute where entity_type_id = 4 and attribute_code = 'YOUR_ATTRIBUTE_CODE_HERE'

Обновление с найденным attribute_idвыше запросом.

UPDATE catalog_product_entity_int SET value = 1 WHERE attribute_id = FOUND_ATTRIBUTE_ID

Я полагаю, вы могли бы сделать выборку с обновлением, но для простоты два SQL-запроса проще всего понять.

ПРИМЕЧАНИЕ: entity_type_id = 4 чаще всего это продукт EAV записей. В случае, если вам необходимо массовое обновление категории или атрибутов клиента, это будет отличаться, также как и таблица, которая обновляется в зависимости от типа атрибута, который вы обновляете. Кроме того, если у вас есть настройка нескольких магазинов, убедитесь, что обратите внимание и условияstore_id


2

В дополнение к ответу Фабиана выше, вы можете обновить несколько полей одновременно. В приведенном ниже примере есть только 2 (на складе, на складе), но вы можете использовать столько, сколько хотите.

    $product_ids = Mage::getModel('catalog/product')
        ->getCollection()
        ->addAttributeToFilter('status', array('eq' => 2)) //only disabled 
        ->getAllIds();

    $attrData = [
        ['attribute_one' => 1],
        ['attribute_two' => 1]
    ];

    $storeId = 0;
    Mage::getSingleton('catalog/resource_product_action')
       ->updateAttributes($product_ids, $attrData, $storeId);

Так что это если вы хотите обновить все продукты с одинаковым значением атрибута - как вы можете адаптировать это для обновления, скажем, 3 продуктов, все с одним атрибутом, но с разными значениями для атрибута? thx
snh_nl

См. Ответ Амит Бера выше: magento.stackexchange.com/a/43924/3433
Сайлас Палмер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.