addAttributeToSelect funktioniert nicht mit 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']);
}

In meiner getLine()Methode bekomme ich nein nameaber addFinalPrice()funktioniert:

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
}

Das gleiche Problem mit image, priceund alle anderen Attribut.

PiTheNumber
quelle

Antworten:

7

Leider core/iteratorfunktioniert das Ressourcenmodell nicht gut mit EAV-Modellen, da es direkt mit der Abfrage zusammenarbeitet und keine der sammlungsspezifischen Funktionen verwendet.

Dies geschieht normalerweise beim Laden einer EAV-Sammlung (ich werde es etwas vereinfachen):

  • Wählen Sie Basisdaten aus der Entitätstabelle aus (dies ist der $collection->getSelect()Fall
  • Laden Sie die Attribute aus den Wertetabellen mit einer zusätzlichen Abfrage und fügen Sie diese Daten jedem geladenen Modell hinzu

Dies alles geschieht in der load()Methode (sehen Mage_Eav_Model_Entity_Collection_Abstract::_loadAttributes()Sie, ob Sie die Implementierungsdetails sehen möchten)

Da der Grund für die Verwendung des Ressourceniterators normalerweise darin besteht, dass Sie nicht alle Daten gleichzeitig laden möchten, können Sie diese Funktion nicht in angemessener Weise verwenden.

Ich habe versucht, stattdessen eine einzelne Abfrage mit Joins zu erstellen, bin jedoch bald auf das Problem gestoßen, dass MySQL "nur" 63 Joins gleichzeitig zulässt. Wenn Sie nur wenige Attribute benötigen, funktioniert dies möglicherweise für Sie.

Andernfalls ist es am besten, die Sammlung in folgenden Blöcken zu laden und zu verarbeiten:

$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
quelle
Ich habe den Iterator wegen eines Speicherbeschränkungsproblems verwendet, aber es stellte sich heraus, dass der Iterator hier noch mehr Speicher verwendet. Ich habe behoben, dass es zur normalen Sammlung zurückkehrt und ini_set('memory_limit','512M');.
PiTheNumber
7

Sie müssen den zweiten Parameter 'inner'wie folgt verwenden:

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

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

PiTheNumber
quelle
Dies ist die JOIN-Lösung, auf die ich mich bezog. Gut, wenn Sie nur ein paar Attribute benötigen, aber versuchen Sie es nicht mitaddAttributeToSelect('*')
Fabian Schmengler
Verwenden Sie 'left', wenn Sie Entitäten einschließen möchten, für die das eav-Attribut überhaupt nicht festgelegt ist.
Siliconrockstar