创建 Luigi 任务图时出现 JSON 序列化错误
Posted
技术标签:
【中文标题】创建 Luigi 任务图时出现 JSON 序列化错误【英文标题】:JSON serialization error when creating a Luigi task graph 【发布时间】:2017-11-06 20:14:42 【问题描述】:我正在尝试使用 Luigi 批量处理几个 Jupyter 笔记本,但遇到了问题。
我有两节课。第一个,transform.py
:
import nbformat
import nbconvert
import luigi
from nbconvert.preprocessors.execute import CellExecutionError
class Transform(luigi.Task):
"""Foo."""
notebook = luigi.Parameter()
requirements = luigi.ListParameter()
def requires(self):
return self.requirements
def run(self):
nb = nbformat.read(self.notebook, nbformat.current_nbformat)
# https://nbconvert.readthedocs.io/en/latest/execute_api.html
ep = nbconvert.preprocessors.ExecutePreprocessor(timeout=600, kernel_name='python3')
try:
ep.preprocess(nb, 'metadata': 'path': "/".join(self.notebook.split("/")[:-1]))
with self.output().open('w') as f:
nbformat.write(nb, f)
except CellExecutionError:
pass # TODO
def output(self):
return luigi.LocalTarget(self.notebook)
这定义了一个将笔记本作为输入的 Luigi 任务(以及运行此任务的可能的先前要求),并且应该运行该笔记本并报告成功或失败作为输出。
要运行 Transform
任务,我有一个很小的 Runner
类:
import luigi
class Runner(luigi.Task):
requirements = luigi.ListParameter()
def requires(self):
return self.requirements
为了完成我的小工作,我会这样做:
from transform Transform
trans = Transform("../tests/fixtures/empty_valid_errorless_notebook.ipynb", [])
from runner import Runner
run_things = Runner([trans])
但这引发了TypeError: Object of type 'Transform' is not JSON serializable
!
我的luigi
任务格式是否正确?如果是这样,run
中的哪个组件使整个类不可序列化是否很明显?如果没有,我应该如何调试?
【问题讨论】:
【参考方案1】:requires()
应该返回一个或多个任务,而不是参数。
例如,
class Runner(luigi.Task):
notebooks = luigi.ListParameter()
def requires(self):
required_tasks = []
for notebook in self.notebooks:
required_tasks.append(Transform(notebook))
return required_tasks
class Transform(luigi.Task):
notebook = luigi.Parameter()
def requires(self):
return []
# then to run at cmd line
luigi --module YourModule Runner --noteboooks '["notebook1.pynb","notebook2.pynb"]'
【讨论】:
所以不可能不提前硬编码依赖关系? 不确定您的意思...您可以对其进行硬编码,我只是指出 requires() 方法的预期返回类型是什么。如果您需要另一个示例,请告诉我。 我想在运行时以编程方式创建一个新任务,将任何额外的要求从上面传递下去。所以假设我在运行时决定我的任务图是 Transform("a.ipynb") --> Transform("b.ipynb") --> Runner。 Runner 需要能够创建trans_a = Transform("a.ipynb", requirements=[])
和Transform("b.ipynb", requirements=[trans_a])
。如果我不能将 requirements
参数作为变量写入,我不确定我该怎么做(至少没有文件 I/O 技巧)。
不确定“运行时”是什么意思。您将传入动态生成任务所需的笔记本列表和其他参数,而不是任务本身作为参数。以上是关于创建 Luigi 任务图时出现 JSON 序列化错误的主要内容,如果未能解决你的问题,请参考以下文章
Newtonsoft.Json.JsonSerializationException:'反序列化对象时出现意外标记:使用动态对象注释
使用 NSDictionary 访问 JSON 序列化时出现异常
使用 GSON 序列化时出现“声明多个 JSON 字段命名”错误
在 Python 中序列化 JSON 时出现“TypeError: (Integer) is not JSON serializable”?
反序列化类时出现“Newtonsoft.Json.JsonSerializationException 无法找到用于类型的构造函数”错误