我正在编写一个脚本,为1万个客户的自定义属性添加值。我在这里有两个问题。
当我们更新产品的自定义属性值时,我们可以使用:
$resource = $product->getResource();
$product->setData($attribute, $value);
$resource->saveAttribute($product,$attribute);
这非常快。但至于客户,它没有getResource()方法。我知道的唯一方法是:$ this-> _customerRepository-> save($ customer);这非常非常慢。那么如何更快地更新客户价值呢?
当我批量更新这些值时,我编写了如下脚本,它在前几百个客户数据更新中运行良好,但随后抛出异常:
(/chroot/home/.../html/vendor/magento/framework/Exception/FileSystemException.php): failed to open stream: Too many open files in /chroot/home/.../html/vendor/composer/ClassLoader.php on line 444
我用Google搜索了这个问题,有人说它与服务器的设置有关。但是,由于我们租用服务器并且无权更改它,我应该如何修改我的代码并使其使用更少的资源?
protected function updateAttributes($customersListData,$output) {
$time_start = microtime(true);
$totalLength = sizeof($customersListData);
foreach ($customersListData as $customerIndex => $singleCustomerData) {
try {
$id = $singleCustomerData['id'];
$customer = $this->_customerRepository->getById($id);
$arrayKeys = array_keys($singleCustomerData);
array_shift($arrayKeys);
foreach ($arrayKeys as $singleKey) {
if (empty($singleCustomerData[$singleKey])) {
$singleCustomerData[$singleKey] = "";
}
$time_now = microtime(true);
$time_used = $time_now - $time_start;
$finished_records = (int)$customerIndex + 1;
$output->writeln("Updating attribute: ".$singleCustomerData[$singleKey].". " .$finished_records ."/".$totalLength." done. will finsih in: ". round($time_used / $finished_records * ($totalLength - $finished_records), 0). "s.");
$customer->setData($singleKey, $singleCustomerData[$singleKey]);
}
$this->_customerRepository->save($customer);
unset($customer);
} catch (\Exception $e) {
$output->writeln($e->getMessage());
continue;
}
}
}
答案 0 :(得分:0)
在这种情况下,foreach中每次迭代有2个数据库请求。这就像一分钟内或某种程度上的20'000个请求。
这是伪代码中的一个想法:
$allCustomers = $this->_customerRepository()->getAll();
$bulkSave[];
foreach($customersListData as $customerIndex => $singleCustomerData)
{
$myCustomer = $allCustomers->find($singleCustomerData['id']);
$bulkSave[] = $myCustomer;
}
$this->_customerRepository()->save($bulkSave);
答案 1 :(得分:0)
在构造函数中使用bellow类
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface
public function execute()
{
$customerId = 2;
if ($customerId) {
$customer = $this->_customerRepositoryInterface->getById($customerId);
$customer->setCustomAttribute('reward_barcode', $barcode);
$this->_customerRepositoryInterface->save($customer);
}
$this->messageManager->addSuccess( __('Your membership successfully updated.') );
}
另类更快的选择
你应该以编程方式使用php out side magento并与之建立数据库连接。获取数据并更新magento属性。这将更快,更容易更新属性。