Один раз сценарий для установки пользовательского атрибута для ~ 1M клиентов - утечка памяти

magento.stackexchange https://magento.stackexchange.com/questions/100537

  •  28-09-2020
  •  | 
  •  

Вопрос

Я пытаюсь запустить одноразовый скрипт (в пользовательском модульном обновлении), чтобы установить новый атрибут Last_order_date на основе даты последнего порядка этого клиента.

У меня есть этот скрипт:

$users = mage::getModel('customer/customer')->getCollection()
           ->addAttributeToSelect('last_order_date');

foreach ($users as $user){
   $lastDate = $user->getData('last_order_date');
   if(empty($lastDate)){
       $orderCollection = Mage::getModel('sales/order')->getCollection()
            ->addFilter('customer_id', $user->getId())
            ->setOrder('created_at', Varien_Data_Collection_Db::SORT_ORDER_DESC)
        ;
        $numberOfOrders = $orderCollection->count();
        if($numberOfOrders!=0){
            $newestOrder = $orderCollection->getFirstItem();
            $lastOrderDate = $newestOrder->getCreatedAt();
            $user->setData('last_order_date', $lastOrderDate);
            $user->save();
        }
   }
}
.

Но это вызывает утечку памяти:

Фатальная ошибка: Разрешено размер памяти 1073741824 байта исчерпаны (пробовал выделить 32 байта) в [..] / Web-root / lib / zend / db / адаптер / pdo / allow.php на линии 292

Что я понимаю, связано с петлими вызовами для Mage::getModel('sales/order').

Как мне добиться этого без повторных звонков?

Это было полезно?

Решение

.

require_once 'app/Mage.php';
Mage::app();

$current_page = isset($_GET['current_page']) ? 1 : $_GET['current_page'];

$users = mage::getModel('customer/customer')->getCollection()
           ->addAttributeToSelect('last_order_date')
           ->setPageSize(100)
           ->setCurPage($current_page);

if($users->count() == 0){
    die('done');
}

foreach ($users as $user){
   $lastDate = $user->getData('last_order_date');
   if(empty($lastDate)){
       $orderCollection = Mage::getModel('sales/order')->getCollection()
            ->addFilter('customer_id', $user->getId())
            ->setOrder('created_at', Varien_Data_Collection_Db::SORT_ORDER_DESC)
        ;
        $numberOfOrders = $orderCollection->count();
        if($numberOfOrders!=0){
            $newestOrder = $orderCollection->getFirstItem();
            $lastOrderDate = $newestOrder->getCreatedAt();
            $user->setData('last_order_date', $lastOrderDate);
            $user->save();
        }
   }
}

$current_page++;

//go to next page
$redirect_url = "http://yoururlhere/set_last_order_date.php?current_page=" . $current_page;
?>
<script type="text/javascript">
    setTimeout("location.href = '<?php echo $redirect_url;?>';", 50);
</script>

Другие советы

Добавлено в Gurutheme Ответить Огромный производительный сервер - использовать saveAttribute вместо save

Так что замените следующее

$user->setData('last_order_date', $lastOrderDate);
        $user->save();
.

с:

$user->setData('last_order_date', $lastOrderDate);
        $user->getResource()->saveAttribute($user,'last_order_date');
.

Таким образом, вы будете сохранять только один атрибут вместо того, чтобы сохранить каждый атрибут модели клиента.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top