addAttributeToSelect não está funcionando com o core / resource_iterator?

8
public function run()
{
    $products = Mage::getModel('catalog/product')
            ->getCollection()
            ->addFinalPrice()
            ->addAttributeToSelect('name')

    Mage::getSingleton('core/resource_iterator')
            ->walk($products->getSelect()->limit(10), array(array($this, 'getLine')));

}

public function getLine($args)
{
    var_dump($args['row']);
}

No meu getLine()método, não recebo, namemas addFinalPrice()funciona:

array(16) {
  ["entity_id"]=>
  string(2) "61"
  ["entity_type_id"]=>
  string(1) "4"
  ["attribute_set_id"]=>
  string(2) "10"
  ["type_id"]=>
  string(6) "simple"
  ["sku"]=>
  string(15) "50-F01010001-03"
  ["has_options"]=>
  string(1) "0"
  ["required_options"]=>
  string(1) "0"
  ["created_at"]=>
  string(19) "2011-07-05 18:30:48"
  ["updated_at"]=>
  string(19) "2014-09-04 07:34:21"
  ["indexed_price"]=>
  string(7) "14.5000"
  ["price"]=>
  string(7) "14.5000"
  ["final_price"]=>
  string(7) "14.5000"
  ["minimal_price"]=>
  string(7) "14.5000"
  ["min_price"]=>
  string(7) "14.5000"
  ["max_price"]=>
  string(7) "14.5000"
  ["tier_price"]=>
  NULL
}

Mesmo problema com image, pricee todos os outros atributos.

PiTheNumber
fonte

Respostas:

7

Infelizmente, o core/iteratormodelo de recursos não funciona bem com modelos EAV, porque trabalha diretamente com a consulta e não usa nenhum dos recursos específicos da coleção.

É o que geralmente acontece ao carregar uma coleção de EAV (simplificarei um pouco):

  • selecione dados básicos da tabela de entidades (é isso que $collection->getSelect()faz
  • carregue os atributos das tabelas de valores com uma consulta adicional e inclua esses dados em cada modelo carregado

Isso tudo acontece no load()método (veja Mage_Eav_Model_Entity_Collection_Abstract::_loadAttributes()se você deseja ver os detalhes da implementação)

Como o motivo para usar o iterador de recursos geralmente é que você não deseja carregar todos os dados de uma vez, não é possível usar esse recurso de maneira razoável.

Tentei criar uma única consulta com junções, mas logo encontrei o problema de que o MySQL "apenas" permite 63 junções por vez. Se você precisar apenas de alguns atributos, ele poderá funcionar para você.

Caso contrário, sua melhor aposta é carregar e processar a coleção em pedaços como este:

$ids = Mage::getModel('catalog/product')
    ->getCollection()
    ->getAllIds();

$page = 1;
do {
    $collection = Mage::getModel('catalog/product')
        ->getCollection()
        ->addIdFilter($ids)
        ->setPageSize(100)
        ->setPage($page);
    $results = $collection->load();
    // do stuff ...
    $page++;
} while ($results->count());
Fabian Schmengler
fonte
Eu usei o iterador devido a um problema de limite de memória, mas ele acabou usando o iterador aqui e usa ainda mais memória. Eu o consertei revertendo para a coleção normal e ini_set('memory_limit','512M');.
PiTheNumber
7

Você deve usar o segundo parâmetro 'inner'assim:

$products = Mage::getModel('catalog/product')
     ->getCollection()
     ->addAttributeToSelect(array('name', 'image'), 'inner');

Consulte: /programming/24614533/magento-collection-iterator-cannot-get-additional-attribute

PiTheNumber
fonte
Esta é a solução JOIN à qual eu estava me referindo. Bom se você só precisa de alguns atributos, mas não tente fazer isso comaddAttributeToSelect('*')
Fabian Schmengler
Use 'left' se desejar incluir entidades nas quais o atributo eav não está definido.
siliconrockstar