气流无法腌制_thread._local对象

时间:2019-08-06 20:38:57

标签: python sqlalchemy airflow

我目前正在DAG中创建一个引擎,并将此sqlalchemy引擎作为参数传递给PythonOperator以执行一些数据库工作。例如

PythonOperator(python_callable=my_callable,
                               op_args=[engine],
                               provide_context=True,
                               task_id = 'my_task',
                               dag=dag)

当我尝试清除任务状态时,出现错误

File "/opt/conda/lib/python3.7/copy.py", line 169, in deepcopy
rv = reductor(4)
TypeError: can't pickle _thread._local objects

这很可能是因为您不能腌制引擎对象:

pickle.dumps(engine)
TypeError: can't pickle _thread._local objects

我想知道是否有解决此问题的好方法,以便我可以有效地使用Airflow网络服务器。我需要传递python可调用的东西,使它可以与数据库进行交互,它可以是连接字符串,但比DAG引擎更容易地在DAG中制作一次引擎并将其传递给所有操作员在每个人中。

1 个答案:

答案 0 :(得分:1)

  

如果有一个好的方法可以解决此问题,那么我可以有效地使用Airflow网络服务器。我需要传递python可调用的东西,使它可以与数据库交互

传递连接字符串是可能的,但是它不应包含凭据(用户ID,密码),因为您不希望凭据以纯格式存储。为此,气流提供了两个概念,变量和连接,请参见this answer for details.

  

在DAG中制造一次引擎并将其传递给所有操作员要比在每个人中制造引擎容易。

实际上-不。乍一看似乎很容易,但是仔细检查却不是一个好主意。

数据库连接本质上是短暂的,仅在特定进程使用的时间内存在。气流任务是在执行时(可能要晚得多,反复执行),在不同的过程中(可能在不同的机器上)实例化的。因此,即使您可以腌制该连接,它在运行时也不会对任务有用,因为它很可能仍然会存在。

通常,从原则上讲,不仅应在气流中,还应始终通过同一过程创建,管理和关闭连接。