气流从与执行文件相同的指定路径中的文件导入时出现问题

时间:2018-08-23 01:49:46

标签: python airflow

为了有效地构造代码,我使用int main( int argc, char ** argv ) { TF_Graph * graph = TF_NewGraph(); TF_SessionOptions * options = TF_NewSessionOptions(); TF_Status * status = TF_NewStatus(); TF_Session * session = TF_NewSession( graph, options, status ); char hello[] = "Hello TensorFlow!"; TF_Tensor * tensor = TF_AllocateTensor( TF_STRING, 0, 0, 8 + TF_StringEncodedSize( strlen( hello ) ) ); TF_Tensor * tensorOutput; TF_OperationDescription * operationDescription = TF_NewOperation( graph, "Const", "hello" ); TF_Operation * operation; struct TF_Output output; TF_StringEncode( hello, strlen( hello ), 8 + ( char * ) TF_TensorData( tensor ), TF_StringEncodedSize( strlen( hello ) ), status ); memset( TF_TensorData( tensor ), 0, 8 ); TF_SetAttrTensor( operationDescription, "value", tensor, status ); TF_SetAttrType( operationDescription, "dtype", TF_TensorType( tensor ) ); operation = TF_FinishOperation( operationDescription, status ); output.oper = operation; output.index = 0; TF_SessionRun( session, 0, 0, 0, 0, // Inputs &output, &tensorOutput, 1, // Outputs &operation, 1, // Operations 0, status ); printf( "status code: %i\n", TF_GetCode( status ) ); printf( "%s\n", ( ( char * ) TF_TensorData( tensorOutput ) ) + 9 ); TF_CloseSession( session, status ); TF_DeleteSession( session, status ); TF_DeleteStatus( status ); TF_DeleteSessionOptions( options ); return 0; } 将函数导入DAG。

结构如下:

sys.path += [ PATH_TO_MODULE ]

- MODULE |_run.py |_aux_functions.py |_config.py 中导入config时会引发错误。

aux_functions导入到aux_functions中。

DAG代码:

run.py

from airflow.operators.python_operator import PythonOperator from airflow import DAG from MODULE_PATHS import PATH_TO_MODULE import datetime import sys sys.path += [ PATH_TO_MODULE ] from run import run_function default_args = { "start_date": datetime.datetime( 2018, 8, 20 ) } with DAG( "run_dag_v1", default_args= default_args, schedule_interval= "0 0 * * *", ) as dag: task = PythonOperator( task_id= "run_function", python_callable= run_function, provide_context= True ) task 导入了run.py,该aux_functions在运行过程中导入了settings from config,这是行不通的。显示的错误是: ImportError: cannot import name 'settings'

# run.py
import aux_functions
.....
def run_function( **kwargs ):
    .....


# aux_functions.py
from config import settings
.....


# config.py
settings = { ..... }

仅在外壳中执行代码时,它可以正常工作,没有任何问题,但是当它通过气流运行时,它始终显示此导入错误。

测试是通过以下方式完成的:airflow test run_dag_v1 run_function 2018-8-21

如果我将settingsconfig移到aux_functions可以正常工作,但是为什么会发生这种情况以及如何避免呢?

1 个答案:

答案 0 :(得分:0)

所以目录结构是这样的:

|_MODULE_1
|   |_ run.py
|   |_ aux_functions.py
|   |_ config.py
|   
|_MODULE_2
    |_ code.py
    |_ config.py

发生的事情是,一个DAG正在导入sys.path += [ PATH_MODULE_1 ],而另一个DAG正在导入sys.path += [ PATH_MODULE_2 ]

在Airflow的运行期间,它将具有错误的配置路径,因此任一DAG总是失败。因此,导入错误,因为另一个配置没有settings对象。它们永远不会同时正常运行。

解决方案是确保每种情况下import config是相对的:import .config。通过这样做,Airflow现在可以在每种情况下识别正确的config.py

我发现管理此问题的最佳方法是导入父文件夹路径from MODULE_PATHS import PATH_MODULES_DIRECTORY并将__init__.py文件添加到模块中,并且在调用同一模块内的其他文件时仅使用相对导入。

因此,新的DAG都具有相同的sys.path,并且可以使用其模块名称导入所有模块。

MODULES_DIRECTORY
    |
    |_MODULE_1
    |   |_ __init__.py
    |   |_ run.py
    |   |_ aux_functions.py
    |   |_ config.py
    |   
    |_MODULE_2
        |_ __init__.py
        |_ code.py
        |_ config.py


from airflow.operators.python_operator import PythonOperator
from airflow                           import DAG

from MODULE_PATHS import PATH_MODULES_DIRECTORY
import datetime
import sys

sys.path += [ PATH_MODULES_DIRECTORY ]

from MODULE_1.run import run_function

default_args = { "start_date": datetime.datetime( 2018, 8, 20 ) }

with DAG( "run_dag_v1", default_args= default_args, schedule_interval= "0 0 * * *", ) as dag:
    task = PythonOperator( task_id= "run_function", python_callable= run_function, provide_context= True )

task


# run.py
import .aux_functions
.....
def run_function( **kwargs ):
    .....


# aux_functions.py
from .config import settings
.....


# config.py
settings = { ..... }