Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 循环空气流量变量问题_Python 3.x_Google Cloud Platform_Airflow_Google Cloud Composer - Fatal编程技术网

Python 3.x 循环空气流量变量问题

Python 3.x 循环空气流量变量问题,python-3.x,google-cloud-platform,airflow,google-cloud-composer,Python 3.x,Google Cloud Platform,Airflow,Google Cloud Composer,我很难在脚本中循环使用气流变量 所以我需要在一个bucket中列出所有以字符串为前缀的文件 下一步通过它循环并执行一些操作 我尝试使用xcomm和subdag,但我想不出来,所以我想出了一个新方法 但它涉及两个脚本 第1个脚本使用我生成的值设置气流变量 下面是代码 #!/usr/bin/env python with DAG('Test_variable', default_args=default_args, schedule_interval=None ) as dag:

我很难在脚本中循环使用气流变量

所以我需要在一个bucket中列出所有以字符串为前缀的文件

下一步通过它循环并执行一些操作

我尝试使用xcomm和subdag,但我想不出来,所以我想出了一个新方法

但它涉及两个脚本

第1个脚本使用我生成的值设置气流变量

下面是代码

#!/usr/bin/env python


with DAG('Test_variable', default_args=default_args,
    schedule_interval=None
) as dag:
    GCS_File_list = GoogleCloudStorageListOperator(
                    task_id= 'list_Files',
                    bucket= 'bucketname',
                    prefix='aaa',
                    delimiter='.csv',
                    google_cloud_storage_conn_id='google_cloud_default'
                    #provide_context = True,
                    #dag = dag
                )
    def update_variable(**context):
        files_list = Variable.get('files_list')
        print(type(Variable.get('files_list')))
        updated_file_list = context['ti'].xcom_pull(task_ids='list_Files')
        #updated_file_list = updated_file_list.strip('][').split(',')
        Variable.set("files_list", updated_file_list)
        #print(updated_file_list)
        #print(type(updated_file_list))

    python_task = PythonOperator(
                             task_id= 'pass_list',
                             provide_context=True,
                             python_callable=update_variable,
                             #op_kwargs={'input_file':file},
                             trigger_rule=TriggerRule.ALL_SUCCESS,
                             #provide_context = True,
                             #xcom_push=True,
                             dag=dag
                            )
    GCS_File_list >> python_task
如您所见,上面的脚本列出了bucket中的文件,并将结果设置为airflow变量

脚本2:导入脚本1中设置的变量值并在其上循环

在这里我可以得到变量值,但不能迭代它

脚本2:

#!/usr/bin/env python
from datetime import datetime, timedelta
from airflow import DAG
from airflowag.models import Variable
from airflow.operators.bash_operator import BashOperator
from airflow.utils.trigger_rule import TriggerRule
from airflow.operators import PythonOperator
from datetime import datetime

YESTERDAY = datetime.combine(
    datetime.today() - timedelta(days=1), datetime.min.time())
BQ_DATASET_NAME = 'abc'
CURRENT_TIME = datetime

files_list_str = Variable.get("files_list")
files_list = files_list_str.strip('][').split(',')
bucket = 'def'

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': YESTERDAY,
    'provide_context': True,
}

def gen_date(input_file,**kwargs):
# stepl1: check for file extension and remove it
idx_extension           = input_file.find(".")
input_file_name         = input_file[:idx_extension]
find_date_time_part     = re.findall("_(\d*?_\d*?_\d*)",input_file_name)
find_date_time_part     = str(find_date_time_part).split('_', 1)[-1].strip(']')
find_date_time_part     = str(find_date_time_part)
find_date_time_part     = re.sub("'",'', find_date_time_part)
find_date_time_part_len = len(find_date_time_part)

if find_date_time_part_len == 15:
    x = [a for a in find_date_time_part.split('_') if a]
    #get the date time part from the list 
    x = (' '.join(x[-2:]))
    #Using strptime to parse the string value as datetime object here our date format is YYYYMMDD hhmiss
    dt_obj = datetime.strptime(x, "%Y%m%d %H%M%S")
    # use strftime to format the date object into desired format in our case YYYY-MM-DD hh:mi:ss
    final_date_formatted = dt_obj.strftime("%Y-%m-%d %H:%M:%S")
    #print(type(find_date_time_part))
    return final_date_formatted
else:
    print("{}_{}".format(files_list,input_file))

with DAG('dag1', default_args=default_args,
schedule_interval=None
        ) as dag:
    for file in enumerate (files_list):
        Python_Task = PythonOperator(
                             task_id='pass_date',
                             provide_context=True,
                             python_callable=gen_date,
                             op_kwargs={'input_file':file},
                             trigger_rule=TriggerRule.ALL_SUCCESS,
                             provide_context = True,
                             #xcom_push=True,
                             dag=dag
                            )
        Python_Task
正如您在这个函数gen_date()中看到的,我正在打印变量名以及else块中的输入文件名

语句print(“{}{}”)的输出格式(文件列表、输入文件) 是['abc.csv','def.csv']_[

我不确定为什么传递“[”而不是输入文件名 谢谢你的建议


我现在看到in-for-loop文件列表被视为字符串而不是列表


如何将文件列表设置为列表而不是字符串。

因此,当我们获得气流变量(文件列表)时它以字符串而不是列表的形式存储和返回,因此我们首先需要将变量转换为列表,然后在该变量上循环。

我也遇到了同样的问题。一个简单的解决方案是使用正则表达式删除“[”,“]“”和“”本身。然后拆分将起作用。然后将创建列表

import re

files_list_str = Variable.get("files_list")
files_list = re.sub('\'|\[|\]','', files_list_str).split(', ') 

这很简单,但节省了很多时间

我可以在DAG中的其他任务中使用该列表