首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >预Prestashop背景批量产品进口

预Prestashop背景批量产品进口
EN

Stack Overflow用户
提问于 2018-10-16 15:21:02
回答 2查看 747关注 0票数 0

我试图在Prestashop电子商务中定期高效地导入15K+产品,解析ASCII文件(3.5MB),并且只使用Prestashop的API。

都在码头下运行,有来自码头枢纽的官方图像。

如果一个具有相同引用字段的产品不存在,我将不得不插入一个新产品,如果它是存在的,以更新它。我开发了一个模块,通过单击un作为一个自定义管理选项卡,它可以工作,但是整个系统会冻结,直到进程完成或结束:(将近77分钟)。我还试图将大文件拆分为500、100、50块,但处理时间线性地减少,这没有多大帮助:

  • 153个秒,500个元素
  • 100个元素的31个平均秒
  • 50个元素的平均15秒

我当然可以每90秒配置一个cron来处理50个元素,并在每晚7-8小时内完成整个导入,但这似乎是一个非常糟糕的折衷方案:每90秒离线15秒。

我不能使用P螺纹,因为这将是一个生产web服务器。

我尝试调优Apache增加的memory_limit、max_input_vars、max_execution_time,但没有任何区别:数据库使用的内存和服务器几乎相同,从450 DB增加到550 DB。

Linux1SMPDebian4.9.110-3+deb9u6 (2018-10-08) x86_64 Versione软件del server: Apache/2.4.10 (Debian) Versione di PHP: 5.6.35 memory_limit=2048M max_input_vars=1000000 max_execution_time=600000 MySQL: 5.6.40

我是否以错误的方式面对这个问题,或者Prestashop的API不是性能良好的,而是用于批量(和性能)产品的进口?

代码语言:javascript
复制
public function batchImportAllProductsFromFile($productsToBeInserted){
    foreach ($productsToBeInserted as $key => $customProduct ) {

        $productIDs = $this->getProductIDsByReference($customProduct->MS_CODMAG);
        if (sizeof($productIDs) == 0) {
            $product = new Product();
        } else if (sizeof($productIDs) == 1) {
            $product = new Product($productIDs[0]);
        } else {
            continue;
        }

        $product->reference = $customProduct->MS_CODMAG;
        $product->name = trim($customProduct->MS_DESCRIZIONE);
        $product->price = $customProduct->MS_PREZZO_1;
        $product->out_of_stock = ($customProduct ->MS_ESAURITO === "S" ? true : false);

        $category = null;

        $msGruppoConverted = $this->buildSubGroupCode($customProduct->MS_GRUPPO, $customProduct->MS_SGRUPPO);

        if ($customProduct->MS_GRUPPO !== 0 && $msGruppoConverted !== 0) {
            $product->id_category = [$customProduct->MS_GRUPPO, $msGruppoConverted];
        } else if ($customProduct->MS_GRUPPO === 0 && $msGruppoConverted !== 0) {
            $product->id_category = [$msGruppoConverted];
        } else if ($customProduct ->MS_GRUPPO !== 0 && $msGruppoConverted === 0) {
            $product->id_category = [$customProduct->MS_GRUPPO];
        }
        try {
            if (sizeof($productIDs) == 0) {
                if ($product->add()) {
                    $product->updateCategories($product->category);
                    $product->addFeatureProductImport($product->id, 1, $customProduct->MS_FAM);
                    //StockAvailable::setQuantity((int)$product->id, 0, $product->quantity, Context::getContext()->shop->id);
                }
            } else if (sizeof($productIDs) == 1) {
                if ($product->update()) {
                    $product->updateCategories($product->category);
                    $alreadySavedFeatures = $product->getFeaturesStatic($productIDs[0]);
                    if (sizeof($alreadySavedFeatures) != 1 || $alreadySavedFeatures[0] != $customProduct->MS_FAM) {
                        $product->deleteProductFeatures();
                        $product->addFeatureProductImport($product->id, 1, $customProduct->MS_FAM);
                    }
                }
            }
        } catch (Exception $e) {
            var_dump("Errore: ", $e, $product);
        }
    }
}

编辑2018年10月22日:

升级到PHP7.2并使用MariaDB 10.3.10没有给我带来任何变化:时间仍然是一样的。带来的好处是安装FS (EXT4),其中DB在/etc/fstab中使用选项barrers=0存储信息:性能从153秒提高到35秒,获得500个元素,总共大约需要18分钟(为77分钟)。

仍然存在的问题是为什么系统在导入时变得没有响应性。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-17 09:10:27

在更新产品之前,您应该检查产品是否需要更新。

以下是我在Prestashop上导入实体时所做的工作(非常简化):

代码语言:javascript
复制
<?php

class myProductImporter {
    protected $products;
    protected $products_checksum;

    public function __construct($products) {
        // Your products from the csv file
        $this->products = $products;
        // Here you get an associative array of products references and checksums
        // ex: array('REF01158' => '489f9ze4f4ze9f49ze8', 'REF15616' => '48949844561233132')
        $this->products_checksum = getProductsChecksum();
    }

    public function run() {
        foreach ($this->products as $product) {
            // If the product ref is present in my checksum list, then its an update
            if (isset($this->products_checksum[$product['reference']])) {
                // If the checksum is different, the product needs an update
                if ($this->products_checksum[$product['reference']] != $this->getChecksum($product)) {
                    $this->updateProduct($product);
                }
            // Else it's a new product
            } else {
                $this->addProduct($product);
            }
        }
    }

    protected function updateProduct($product) {
        $PSProduct = getProductByReferebce($product['reference']);
        // Update your product and save its new checksum
    }

    protected function addProduct($product) {
        $PSProduct = new Product();
        // Create the product and save its checksum
    }

    protected function getChecksum($product) {
        // Create a string containing all your product properties
        $checksum = $product['reference'];
        $checksum .= $product['name'];
        $checksum .= $product['description'];
        $checksum .= $product['id_category'];
        return md5($checksum);
    }
}

当没有修改时,您的导入将立即完成,因为没有任何查询正在处理。

关于您安装的冻结,这似乎是一个码头问题,而不是连接到Prestashop。

正如@bruno所提到的,您应该考虑升级到PHP7。

票数 1
EN

Stack Overflow用户

发布于 2018-10-22 16:49:07

真正解决了Prestashop在导入产品时被困的问题的是,将我的代码从位于ModuleAdminController中的代码转移到WebserviceSpecificManagementInterface:中,这样导入就不会使系统饱和。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52838870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档