luigi:为了调试目的而重新运行任务?

时间:2017-01-23 18:06:07

标签: debugging workflow luigi

我正在编写一些luigi工作流程,我正在尝试调试任务。为了做到这一点,我需要反复使用相同的参数重新运行这些任务,直到最后,他们做我想做的事。

我知道luigi任务是幂等的,因此在给出与之前相同的输入时通常不会重新运行,这正是 工作流程之后所需要的被调试并在生产中。但是,在开发过程中,使用精确,相同的输入和输出重新运行工作流程是有用的 - 而且我认为是必要的。

我知道我可以覆盖complete()方法,在开发过程中在每个任务中返回False。但是,这会使任务处于未完成状态。

我正在寻找一种方法来将我的工作流设置为在某种“开发”或“调试”模式下运行,因此我可以反复运行并重新运行它,即使在所有任务完成时也是如此正确运行,直到我确定工作流程正在按照我的意愿行事。

在路易吉有没有办法做到这一点?

提前谢谢。

================稍后添加================

根据我在下面的评论,似乎将输入参数更改为任务不会导致重新运行。只有当其output()方法返回唯一值时,该任务才能重新运行。这似乎违背了“幂等”的定义,因为更改输入参数应该将一个真正的幂等任务视为一个新的,唯一的实体,而不管它是否恰好返回与另一个具有不同输入参数的调用相同的输出。

以下代码说明了该问题。 “x”参数确定output()方法返回的文件名,而“y”参数用于输出内容,但不用于输出文件的名称。

如果我用“--x 10 --y 20”然后“--x 10 --y 30”调用我的工作流程,则第二次调用不会导致任何一个任务重新运行。我认为,这是不正确的行为。但是,如果我使用“--x 10 --y 20”后跟“--x 11 --y 20”调用工作流程,则两个任务都将重新运行。

#!/usr/bin/python3                                                                                                              
# -*- python -*-                                                                                                                

import luigi

class Child(luigi.Task):

    x = luigi.Parameter()
    y = luigi.Parameter()

    def requires(self):
        return []

    def output(self):
        return luigi.LocalTarget("child_{}.txt".format(self.x))

    def run(self):
        with self.output().open('w') as f:
            f.write('{} {}\n'.format(self.x, self.y))

class Parent(luigi.Task):

    x = luigi.Parameter()
    y = luigi.Parameter()

    def requires(self):
        return [ Child(self.x, self.y) ]

    def output(self):
        return luigi.LocalTarget("parent_{}.txt".format(self.x))

    def run(self):
        with self.input()[0].open() as fin, self.output().open('w') as fout:
            for line in fin:
                fout.write("from command line: --x {} --y {}, from child: {}\n".format(self.x, self.y, line.strip()))

if __name__ == '__main__':
    luigi.run()

1 个答案:

答案 0 :(得分:0)

正如你所说,调试模式会很棒。但我认为路易吉没有这样的东西。

您可以执行的一项技巧是在任务调用addressValid方法之前删除目标,如图所示here。您的任务必须是此类的子类,因此您可以在执行之前使用complete()参数重置它。

请注意,只有当您的任务将本地文件作为输出时,此解决方案才有效。您必须对其进行自定义才能删除S3键/存储桶,数据库表或行等。