Debugging 为了调试的目的重新运行任务?

Debugging 为了调试的目的重新运行任务?,debugging,workflow,luigi,Debugging,Workflow,Luigi,我正在编写一些luigi工作流,并尝试调试这些任务。为了做到这一点,我需要用相同的参数一遍又一遍地重新运行这些任务,直到它们完成我想要的任务为止 我知道luigi任务是幂等的,因此,在给定与前面相同的输入时,通常不会重新运行,这正是在调试工作流并投入生产后所需要的。然而,在开发过程中,使用完全相同的输入和输出重新运行工作流是有用的,而且我认为这是必要的 我知道我可以在开发过程中重写complete()方法,在每个任务中返回False。但是,这会使任务处于未完成状态 我正在寻找一种方法,将我的工作

我正在编写一些luigi工作流,并尝试调试这些任务。为了做到这一点,我需要用相同的参数一遍又一遍地重新运行这些任务,直到它们完成我想要的任务为止

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

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

我正在寻找一种方法,将我的工作流设置为以某种“开发”或“调试”模式运行,这样我就可以反复运行并重新运行它,直到完成为止,即使所有任务都正确运行,直到我确定工作流正是我想要的

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

先谢谢你

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

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

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

如果我用“-x10--y20”和“-x10--y30”调用工作流,则第二次调用不会导致任何一个任务重新运行。我认为这是不正确的行为。但是,如果我用“-x10--y20”后跟“-x11--y20”调用工作流,这两个任务实际上都将重新运行

#!/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()

正如您所说,调试模式将非常好。但我认为路易吉没有这样的东西

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


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

非常感谢。我的应用程序正在创建S3存储桶和红移表,为了重新运行任务,我确实不得不删除这些项。不幸的是,这在某些情况下没有帮助。但是,我想我可能偶然发现了一个解决方案:如果每次对工作流运行调试测试时生成一个唯一的参数,并将此参数作为参数传递给每个任务,那么我确实可以重新运行工作流的所有任务。我将我的任务结构化为每个任务都以一个DictParameter作为参数,并在调试运行期间传入这个唯一的ID。这似乎有效。明天早上我会更全面地测试这一点,并在这里报告我的发现。嗯,我错了。我错误地认为,通过更改任务的输入(即,添加唯一的输入参数),Luigi将始终重新运行任务。然而,情况显然并非如此。无论任务的输入参数如何,在重新运行任务之前,输出必须是唯一的。这似乎违背了“幂等元”的严格定义。。。但我想我们必须接受这个。哦,好吧。