Maneira mais rápida de atualizar um atributo em todos os produtos

Respostas:

22

Oi Magento fornecer um atributo por código abaixo

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

Exemplo:

$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');

Usando a coleção de produtos:

$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');


}
Amit Bera
fonte
Isso é super rápido! Eu tentei Mage::getSingleton('catalog/product_api')->update();e Mage::getSingleton('catalog/product_action')->updateAttributes(). product_api levou 1,7 segundos na média e product_action levou 1,0 segundos na média. no entanto, $product->getResource()->saveAttribute()levou em média 0,04 segundos em média. Obrigado!
Joshua Pacote
Existe algo semelhante a esse método que pode atualizar atributos em um determinado nível de loja?
Robbie Averill
Thx @Amit Bera - 1 pergunta restante;) também há uma maneira de salvar vários atributos de uma só vez? De alguém teria que dar uma volta pela $product->getResource()->saveAttributeação. VALEU!!
snh_nl
@amit bera, pls olhar para este magento.stackexchange.com/questions/201757/… o que devo fazer?
precisa
@amit: Eu preciso de como posso granel website mudança (atributo atualização em multi-loja)
ZUS
18

Escreva uma consulta SQL.

Segunda melhor maneira (e a que eu recomendo): \Mage_Catalog_Model_Resource_Product_Action::updateAttributes

Exemplo de código por 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);

Como isso funcionaria com valores de seleção múltipla? 'Adiciona' o valor ou sobrescreve outros valores pré-selecionados

As seleções múltiplas são normalmente salvas como números inteiros separados por vírgula, como 27,42,4711. Portanto, se você alterar o valor para dizer 1, os outros valores serão perdidos. Mas o que você pode fazer é algo como CONCAT(value, ',1')adicionar o novo valor ao final, separado por uma vírgula. Eu acho que mesmo se você adicionar um valor duas vezes, isso não é problema, porque o Magento o filtra na próxima vez que o item é salvo e ignora o segundo valor.

Fabian Blechschmidt
fonte
Isso atualizará apenas 1k linhas por vez, não tão rápido: github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/…
B00MER
Quando entendo o código corretamente, ele grava a cada 1000 linhas, mas atualiza tudo em uma linha.
Fabian Blechschmidt
1
Obrigado @FabianBlechschmidt! Aqui está o meu exemplo de código ( essência ):<?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);
Max Uroda
1
O problema dessa abordagem é que ela não reindexa os produtos, portanto, você pode não ver alterações no frontend e apenas vê-las no painel de administração. Para também reindexar após a atualização, você pode alterar Mage::getSingleton('catalog/resource_product_action')para Mage::getModel('catalog/product_action')exatamente os mesmos parâmetros mencionados acima.
Shampoo3 de
1
@snh_nl atualizou a resposta. Espero que isso responda à sua pergunta #
Fabian Blechschmidt
5

10k produtos, use SQL. O EAV apenas turva as águas. Por pergunta é a maneira mais rápida.

Encontre attribute_id

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

Atualize com a pesquisa encontrada attribute_idacima.

UPDATE catalog_product_entity_int SET value = 1 WHERE attribute_id = FOUND_ATTRIBUTE_ID

Suponho que você poderia fazer uma subseleção com atualização, mas, para simplificar, é mais fácil entender duas consultas SQL.

NOTA: entity_type_id = 4 é sempre a entrada do EAV do produto. Caso você precise atualizar em massa os atributos da categoria ou do cliente, isso será diferente, assim como a tabela atualizada com base em que tipo de atributo é a sua atualização. Além disso, se você tiver uma configuração de várias lojas, certifique-se de observar estore_id

B00MER
fonte
2

Além da resposta de Fabian acima, você pode atualizar vários campos por vez. O exemplo abaixo tem apenas 2 (em estoque, status de estoque), mas você pode usar quantos quiser.

    $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);
Silas Palmer
fonte
Portanto, se você deseja atualizar todos os produtos para o mesmo valor de atributo - como você pode adaptar isso para atualizar, digamos, 3 produtos, todos com o mesmo atributo, mas com valores diferentes para o atributo? thx
snh_nl
Veja a resposta de Amit Bera acima: magento.stackexchange.com/a/43924/3433
Silas Palmer