【问题标题】:Symfony console to cron or task schedules in combination with task runnerSymfony 控制台到 cron 或任务计划与任务运行器相结合
【发布时间】:2018-11-09 21:24:34
【问题描述】:

对于我的项目,我必须导入 12-15 个文件,从 CSV、xml 到 gz。由于所有文件都有自己的结构,我必须为每个文件创建 1 个命令。但这太多了,想要为所有文件创建一个常规导入。

要求:

  • 导入脚本应该每小时运行一次
  • 导入脚本应该是导入的类别 + 来自导入的产品
  • 导入脚本必须检查我的类别是否与导入的类别匹配,如果是,则应将信息添加到 如果不忽略数据库。
  • 如果在后台导入,则导入不应影响网站。

我目前的指挥权:

$handle = fopen("https://example.csv",'r');

$output->writeln('Downloading done!');

$categortArray = [];
$categortA = [];
while (($row = fgetcsv($handle, 4096, ";")) !== FALSE)
{
    $categortA [ $row[21]] = $row[23] ;
    $categortArray [] = $row[21];
}

$output->writeln('Updating category list !');
$result = array_unique($categortArray);
$result2 = array_unique($categortA);

$distributor = $distributor->findByName("Name of Distributor");

foreach ($result as $productgroup) {
    $result = $categoryRepository->findByTitle($productgroup);
    if (empty($result)){
        $category = new Category();
        $category->setTitle($productgroup);
        $category->setDescription("Category Description");
        $category->setDistributor($distributor);

        $categoryService->create($category);
    }
}

foreach ($result2 as $key => $productgroup) {
    $result = $categoryRepository->findByTitle($key);

    /** @var $result Category */
    if ($result !== null) {
        $category = new Category();
        $category->setTitle($productgroup);
        $category->setParent($result[0]);
        $category->setDescription("Name of Distributor");
        $category->setDistributor($distributor);

        $categoryService->create($category);
    }
}

while (($row = fgetcsv($handle, 4096, ";")) !== FALSE)
{

    foreach ($child as $c) {
        if ($c->getTitle() === $row['21']) {
            $product = new Product();
            $product->setName($row[1]);
            $product->setCategory($categoryTop);
            $product->setSku($row[14]);
            $product->setEanUpc($categoryTop->getId());
            $this->productService->save($product);
        }
    }
}

我能想到的选项:

  • 在 1 个命令中提取所有自动导入脚本并在每个命令中运行它 小时。这个选项并不难,但我认为这不是最好的解决方案,因为它会占用我服务器上的大量资源。
  • 结合任务运行器创建一个任务调度程序,我们记录不同步骤的每个事件,例如下载文件、读取文件、检查是否存在、检查类别是否匹配、检查产品是否存在、检查产品库存是否充足迄今为止等。对于这个选项,我想创建自己的调度程序 + 运行程序,但没有太多经验,不知道这是否对我的项目有帮助。由于每个任务都将设置在队列中,因此更容易检查是否有故障

也感谢我对当前 Symfony 命令的建议。

【问题讨论】:

    标签: php symfony cron


    【解决方案1】:

    我过去解决了类似的问题,现在这些建议取决于您需要同步多少数据(我有大约 8 个源,每个源大约 10 000 个项目,同步时间不晚于 15 分钟)。

    解决方案的架构是这样的

    • 对于您拥有 Tranformer 的每个源,它会下载源文件并将其解析为一个常见的 TransformedDTO,在您的情况下,它可能是一个包含类别的产品或两个用于 2 个不同处理器的转换对象
    • 接下来你有处理器 - 这个处理器得到了 TransformedDTO,现在为了优化,我计算了数据的校验和,并与上次运行的基于产品的校验和进行了比较。现在仅在需要时进行更新。如果您只插入产品,则不需要此步骤。
    • 在这里您可以执行此操作,该处理器只需检查产品是否更改,如果是,您将更新添加到队列并让不同的处理器处理。但这只是下一个可能的步骤。

    此解决方案的优点:

    • 添加新的导入只需要编写一个 Transformer
    • 您的处理器中可以有一些缓存/优化逻辑(这通常是瓶颈,因为它需要执行相当多的操作),但由于它是共享的,因此有空间,并且一个优化会影响所有。

    对于计划,取决于您的需求 - 我会坚持在不同时间运行不同计划的可能性,并检查源更新的时间间隔并将更新时间与之同步。

    TransformedDTO 示例。它只不过是数据的占位符,用作处理器的输入和输出转换器。

    class Product {
        public $sku;
        public $category;
        public $name;
        // Everything else which your processor know how to process
    }
    

    【讨论】:

    • @m-kebza 你对 Transformer / TreansformerDTO 是什么意思你能详细说明一下吗?
    • DTO - 数据传输对象,它只是一个常见的对象,将用作数据的填充物。所以处理器有某种接口/合同,他们知道他们会得到什么数据。
    • @m-kebza 你有例子吗?
    • 添加了小例子,但其余的主要取决于您的具体逻辑。
    • @M-kebza 但是这个公共sku等已经包含在产品实体模型中了,有什么区别?
    猜你喜欢
    • 2020-12-02
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多