2011-11-17 18 views
7

He escrito bastantes guiones para actualizar mi catálogo de productos en función de algunos u otros parámetros. En cada uno de ellos la lógica de base es algo Algo parecido a esto ...Magento: actualizar catálogos de productos más rápido

 //Get collection 
    $collection = Mage::getModel('catalog/product')->getCollection(); 
    $collection->addAttributeToSelect('sku'); 
$collection->addAttributeToSelect('publihser'); 
    $collection->addFieldToFilter(array(array('attribute'=>'publisher','eq'=>$publisher))); 

    // for each product in collection do a individual save 
    foreach ($collection as $product) { 
    $product->setSKU($newValue); 
    $product->save(); 
      } 

Aunque este trabajo, cada uno ahorra es una actualización de consulta SQL y el hecho es que tener un catálogo muy grande, esto es bastante lento.

Me preguntaba si esto podría acelerarse haciendo solo guardar en la colección en lugar del producto.

+0

Esto se ejecuta en el navegador o cli? – djdy

+2

prueba [MAGMI] (http://sourceforge.net/apps/mediawiki/magmi/index.php?title=Magmi_Wiki). –

+0

@djdy Esto se ejecuta en CLI ... pero también se puede ejecutar en la interfaz web. – TheVyom

Respuesta

21

Hay varias cosas que puede hacer para escribir un script de actualización mucho más rápido. No sé cómo obtendrá algunas de sus variables, por lo que deberá modificarlas para que funcionen en su caso, pero el siguiente código debería ser mucho más rápido que la forma en que lo está haciendo actualmente. por ejemplo:

// Set indexing to manual before starting updates, otherwise it'll continually get slower as you update 
$processes = Mage::getSingleton('index/indexer')->getProcessesCollection(); 
$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL)); 
$processes->walk('save'); 

// Get Collection 
$collection = Mage::getModel('catalog/product')->getCollection() 
    ->addAttributeToSelect('sku') 
    ->addAttributeToSelect('publihser') 
    ->addFieldToFilter(array(array('attribute'=>'publisher','eq'=>$publisher))); 


function productUpdateCallback($args){ 
    $product = Mage::getModel('catalog/product'); 

    $product->setData($args['row']); 

    $productId = $product->getId(); 

    $sku = 'yourSku'; 

    // Updates a single attribute, much faster than calling a full product save 
    Mage::getSingleton('catalog/product_action') 
     ->updateAttributes(array($productId), array('sku' => $sku), 0); 
} 

// Walk through collection, for large collections this is much faster than using foreach 
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array('productUpdateCallback')); 


// Reindex all 
$processes->walk('reindexAll'); 
// Set indexing back to realtime, if you have it set to manual normally you can comment this line out 
$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME)); 
$processes->walk('save'); 
+0

Gracias @Jasuten. Tu respuesta está llena de ideas que puedo usar para mejorar la velocidad. – TheVyom

+2

Obtengo 'Llamar a una función miembro getAttributeId() en un no objeto en \ app \ code \ core \ Mage \ Catalog \ Model \ Resource \ Product \ Action.php en la línea 69' cuando intento actualizar' category_ids'. ¿No hay forma de modificar ese "atributo" (no es realmente un atributo) de esta manera, o de ninguna manera más rápido que '$ product-> setCategoryIds ('1,2,3') -> save();' –

Cuestiones relacionadas