ফাইলনামের অ্যারের উপর ভিত্তি করে পিতৃ দাগ থেকে গতিশীল সাবড্যাগগুলি তৈরি করার চেষ্টা করছেন


10

আমি এয়ারফ্লো ব্যবহার করে "নন-মোছা" বালতি (মানে আমি ফাইলগুলি মুছতে পারি না) থেকে এসসি ফাইলগুলি জিসিএসে সরানোর চেষ্টা করছি am আমার নিশ্চয়তা দেওয়া যায় না যে প্রতিদিন নতুন ফাইল থাকবে but তবে আমাকে অবশ্যই প্রতিদিন নতুন ফাইলগুলি পরীক্ষা করা উচিত।

আমার সমস্যা হ'ল সাবড্যাগগুলির গতিশীল সৃষ্টি। যদি ফাইলগুলি থাকে তবে আমার সাবড্যাগগুলি দরকার। যদি ফাইল না থাকে তবে আমার সাবড্যাগের প্রয়োজন নেই। আমার সমস্যা হ'ল আপস্ট्रीम / ডাউনস্ট्रीम সেটিংস। আমার কোডে এটি ফাইলগুলি সনাক্ত করে, তবে সাবড্যাগগুলি সেগুলি যেমন বলে মনে হচ্ছে তেমনভাবে সরিয়ে দেয় না। আমি কিছু মিস করছি

এখানে আমার কোড:

from airflow import models
from  airflow.utils.helpers import chain
from airflow.providers.amazon.aws.hooks.s3 import S3Hook
from airflow.operators.python_operator import PythonOperator, BranchPythonOperator
from airflow.operators.dummy_operator import DummyOperator
from airflow.operators.subdag_operator import SubDagOperator
from airflow.contrib.operators.s3_to_gcs_operator import S3ToGoogleCloudStorageOperator
from airflow.utils import dates
from airflow.models import Variable
import logging

args = {
    'owner': 'Airflow',
    'start_date': dates.days_ago(1),
    'email': ['sinistersparrow1701@gmail.com'],
    'email_on_failure': True,
    'email_on_success': True,
}

bucket = 'mybucket'
prefix = 'myprefix/'
LastBDEXDate = int(Variable.get("last_publish_date"))
maxdate = LastBDEXDate
files = []

parent_dag = models.DAG(
    dag_id='My_Ingestion',
    default_args=args,
    schedule_interval='@daily',
    catchup=False
)

def Check_For_Files(**kwargs):
    s3 = S3Hook(aws_conn_id='S3_BOX')
    s3.get_conn()
    bucket = bucket
    LastBDEXDate = int(Variable.get("last_publish_date"))
    maxdate = LastBDEXDate
    files = s3.list_keys(bucket_name=bucket, prefix='myprefix/file')
    for file in files:
        print(file)
        print(file.split("_")[-2])
        print(file.split("_")[-2][-8:])  ##proves I can see a date in the file name is ok.
        maxdate = maxdate if maxdate > int(file.split("_")[-2][-8:]) else int(file.split("_")[-2][-8:])
    if maxdate > LastBDEXDate:
        return 'Start_Process'
    return 'finished'

def create_subdag(dag_parent, dag_id_child_prefix, file_name):
    # dag params
    dag_id_child = '%s.%s' % (dag_parent.dag_id, dag_id_child_prefix)

    # dag
    subdag = models.DAG(dag_id=dag_id_child,
              default_args=args,
              schedule_interval=None)

    # operators
    s3_to_gcs_op = S3ToGoogleCloudStorageOperator(
        task_id=dag_id_child,
        bucket=bucket,
        prefix=file_name,
        dest_gcs_conn_id='GCP_Account',
        dest_gcs='gs://my_files/To_Process/',
        replace=False,
        gzip=True,
        dag=subdag)


    return subdag

def create_subdag_operator(dag_parent, filename, index):
    tid_subdag = 'file_{}'.format(index)
    subdag = create_subdag(dag_parent, tid_subdag, filename)
    sd_op = SubDagOperator(task_id=tid_subdag, dag=dag_parent, subdag=subdag)
    return sd_op

def create_subdag_operators(dag_parent, file_list):
    subdags = [create_subdag_operator(dag_parent, file, file_list.index(file)) for file in file_list]
    # chain subdag-operators together
    chain(*subdags)
    return subdags

check_for_files = BranchPythonOperator(
    task_id='Check_for_s3_Files',
    provide_context=True,
    python_callable=Check_For_Files,
    dag=parent_dag
)

finished = DummyOperator(
    task_id='finished',
    dag=parent_dag
)

decision_to_continue = DummyOperator(
    task_id='Start_Process',
    dag=parent_dag
)

if len(files) > 0:
    subdag_ops = create_subdag_operators(parent_dag, files)
    check_for_files >> decision_to_continue >> subdag_ops[0] >> subdag_ops[-1] >> finished


check_for_files >> finished

এই ডিএজিএস এর ব্যাক-এন্ডে কোন ধরণের কাজ চলে তা হ'ল এই sparkচাকরিগুলি বা কোনও pythonস্ক্রিপ্ট এবং আপনি এটির মতো livyবা অন্য কোনও পদ্ধতি চালানোর জন্য কী ব্যবহার করছেন
আশ্বিন অগ্রবাল

আমি দুঃখিত, আমি প্রশ্নটি বুঝতে পারি না। আপনি কি দয়া করে বিশ্রাম দিন?
arcee123

আমি বোঝাতে চাইছি আপনি কেবল সাধারণ অজগর স্ক্রিপ্ট ব্যবহার করছেন এবং কোনও স্পার্ক কাজ সঠিকভাবে ব্যবহার করছেন না?
আশ্বিন অগ্রবাল

হ্যাঁ. সাধারণ অপারেটরগুলি যা এয়ারফ্লোতে ডিফল্ট are আমি এসসি-তে ফ্ল্যাগড ফাইলগুলির ভিত্তিতে একটি গতিশীল হারে বিদ্যমান অপারেটরদের যুক্ত করতে চাই আমি জিসিএসে প্রবেশ করতে চাই।
arcee123

filesখালি তালিকা কেন ?
ওলুওয়াফেমি সুলে

উত্তর:


3

নীচে বায়ু প্রবাহে একটি গতিশীল ডিএজি বা সাব-ড্যাগ তৈরির প্রস্তাবিত উপায় রয়েছে, যদিও অন্যান্য উপায়ও রয়েছে, তবে আমার ধারণা এটি আপনার সমস্যার ক্ষেত্রে বেশিরভাগ ক্ষেত্রে প্রযোজ্য।

প্রথমে একটি ফাইল তৈরি করুন (yaml/csv)যাতে সমস্ত s3ফাইল এবং অবস্থানের তালিকা অন্তর্ভুক্ত থাকে , আপনার ক্ষেত্রে আপনি সেগুলি তালিকায় সংরক্ষণের জন্য একটি ফাংশন লিখেছেন, আমি বলব এগুলি একটি পৃথক yamlফাইলে সংরক্ষণ করুন এবং এয়ারফ্লো এনভিতে রান সময়ে লোড করুন এবং তারপরে তৈরি করুন DAGs।

নীচে একটি নমুনা yamlফাইল রয়েছে: dynamicDagConfigFile.yaml

job: dynamic-dag
bucket_name: 'bucket-name'
prefix: 'bucket-prefix'
S3Files:
    - File1: 'S3Loc1'
    - File2: 'S3Loc2'
    - File3: 'S3Loc3'

আপনার Check_For_Filesফাংশনটি কোনও yamlফাইলে সংরক্ষণ করার জন্য আপনি তাদের ফাংশনটি পরিবর্তন করতে পারেন ।

এখন আমরা গতিশীল ডাগ তৈরির দিকে এগিয়ে যেতে পারি:

প্রথমে ডামি অপারেটর ব্যবহার করে দুটি কার্য নির্ধারণ করুন, এটি শুরু এবং শেষ টাস্ক। এই জাতীয় কাজগুলি সেইগুলিতে যা আমরা DAGতাদের মধ্যে গতিশীলভাবে কার্য তৈরি করে তৈরি করতে যাচ্ছি :

start = DummyOperator(
    task_id='start',
    dag=dag
)

end = DummyOperator(
    task_id='end',
    dag=dag)

ডায়নামিক ডিএজি: আমরা PythonOperatorsএয়ারফ্লোতে ব্যবহার করব । ফাংশনটি আর্গুমেন্ট হিসাবে টাস্ক আইডি গ্রহণ করা উচিত; একটি অজগর ফাংশন কার্যকর করা হবে, অর্থাত্ পাইথন অপারেটরের জন্য পাইথন_ক্যাল্লেবল; এবং কার্যকর করার সময় ব্যবহারযোগ্য আরোগুলির একটি সেট।

একটি যুক্তি অন্তর্ভুক্ত করুন task id। সুতরাং, আমরা গতিশীল উপায়ে উত্পন্ন কাজগুলির মধ্যে ডেটা বিনিময় করতে পারি, উদাহরণস্বরূপ, এর মাধ্যমে XCOM

এই গতিশীল ড্যাগের মতো আপনি নিজের ক্রিয়াকলাপটি নির্দিষ্ট করতে পারেন s3_to_gcs_op

def createDynamicDAG(task_id, callableFunction, args):
    task = PythonOperator(
        task_id = task_id,
        provide_context=True,
        #Eval is used since the callableFunction var is of type string
        #while the python_callable argument for PythonOperators only receives objects of type callable not strings.
        python_callable = eval(callableFunction),
        op_kwargs = args,
        xcom_push = True,
        dag = dag,
    )
    return task

শেষ পর্যন্ত ইয়ামল ফাইলে উপস্থিত অবস্থানের ভিত্তিতে আপনি গতিশীল ড্যাগগুলি তৈরি করতে পারেন, প্রথমে yamlনীচের মতো ফাইলটি পড়ুন এবং ডায়নামিক ড্যাগ তৈরি করতে পারেন :

with open('/usr/local/airflow/dags/config_files/dynamicDagConfigFile.yaml') as f:
    # use safe_load instead to load the YAML file
    configFile = yaml.safe_load(f)

    #Extract file list
    S3Files = configFile['S3Files']

    #In this loop tasks are created for each table defined in the YAML file
    for S3File in S3Files:
        for S3File, fieldName in S3File.items():

            #Remember task id is provided in order to exchange data among tasks generated in dynamic way.
            get_s3_files = createDynamicDAG('{}-getS3Data'.format(S3File), 
                                            'getS3Data', 
                                            {}) #your configs here.

            #Second step is upload S3 to GCS
            upload_s3_toGCS = createDynamicDAG('{}-uploadDataS3ToGCS'.format(S3File), 'uploadDataS3ToGCS', {'previous_task_id':'{}-'})

#write your configs again here like S3 bucket name prefix extra or read from yaml file, and other GCS config.

চূড়ান্ত ডিএজি সংজ্ঞা:

ধারণাটি হ'ল

#once tasks are generated they should linked with the
#dummy operators generated in the start and end tasks. 
start >> get_s3_files
get_s3_files >> upload_s3_toGCS
upload_s3_toGCS >> end

ক্রমে সম্পূর্ণ এয়ারফ্লো কোড:

import yaml
import airflow
from airflow import DAG
from datetime import datetime, timedelta, time
from airflow.operators.python_operator import PythonOperator
from airflow.operators.dummy_operator import DummyOperator

start = DummyOperator(
    task_id='start',
    dag=dag
)


def createDynamicDAG(task_id, callableFunction, args):
    task = PythonOperator(
        task_id = task_id,
        provide_context=True,
        #Eval is used since the callableFunction var is of type string
        #while the python_callable argument for PythonOperators only receives objects of type callable not strings.
        python_callable = eval(callableFunction),
        op_kwargs = args,
        xcom_push = True,
        dag = dag,
    )
    return task


end = DummyOperator(
    task_id='end',
    dag=dag)



with open('/usr/local/airflow/dags/config_files/dynamicDagConfigFile.yaml') as f:
    configFile = yaml.safe_load(f)

    #Extract file list
    S3Files = configFile['S3Files']

    #In this loop tasks are created for each table defined in the YAML file
    for S3File in S3Files:
        for S3File, fieldName in S3File.items():

            #Remember task id is provided in order to exchange data among tasks generated in dynamic way.
            get_s3_files = createDynamicDAG('{}-getS3Data'.format(S3File), 
                                            'getS3Data', 
                                            {}) #your configs here.

            #Second step is upload S3 to GCS
            upload_s3_toGCS = createDynamicDAG('{}-uploadDataS3ToGCS'.format(S3File), 'uploadDataS3ToGCS', {'previous_task_id':'{}-'})

#write your configs again here like S3 bucket name prefix extra or read from yaml file, and other GCS config.


start >> get_s3_files
get_s3_files >> upload_s3_toGCS
upload_s3_toGCS >> end

তোমাকে অনেক ধন্যবাদ. সুতরাং আমার একটি সমস্যা হ'ল নতুন ফাইল না থাকলে কী হয়? আমি যে সমস্যার মুখোমুখি হচ্ছি সেগুলির মধ্যে একটি হ'ল এই জায়গায় সবসময় ফাইল থাকবে, তবে টানা যাবার জন্য নতুন ফাইলগুলি গ্যারান্টিযুক্ত নয়, যার অর্থ এই বিভাগটি upload_s3_toGCSবিদ্যমান থাকবে না এবং বায়ু প্রবাহে ত্রুটি ঘটবে।
আরসি 123

yamlএই সমস্ত ফাইল একবার জিসিএসে আপলোড হয়ে গেলে আপনি ফাইলটি ফাইলগুলি সরিয়ে সমস্যার সমাধান করতে পারেন , এই পদ্ধতিতে কেবল নতুন ফাইলই yamlফাইলটিতে উপস্থিত থাকবে । এবং যদি কোনও নতুন ফাইল না yamlথাকে তবে ফাইলটি খালি থাকবে এবং কোনও গতিশীল ড্যাগ তৈরি হবে না। এই কারণেই yamlফাইলটি তালিকায় থাকা ফাইলগুলি সংরক্ষণের তুলনায় অনেক ভাল বিকল্প।
আশ্বিন অগ্রবাল

এই yamlফাইলটি একটি উপায়ে এস 3 ফাইলের লগিং বজায় রাখতে সহায়তা করবে, মনে করুন যে যদি এস 3 ফাইলের কোনওটি জিসিএসে আপলোড করতে ব্যর্থ হয়, তবে আপনি সেই ফাইলের সাথে সম্পর্কিত একটি পতাকাও বজায় রাখতে পারেন এবং তারপরে পরবর্তী ডিএজি রানে এগুলি আবার চেষ্টা করতে পারেন।
আশ্বিন অগ্রবাল

এবং যদি কোনও নতুন ফাইল না থাকে তবে আপনি ifড্যাগের সামনে একটি শর্ত yamlরাখতে পারেন যা নতুন ফাইলগুলি চালনা করে যদি এটি ফাইলগুলিতে নতুন ফাইলগুলির জন্য পরীক্ষা করে তা অন্যথায় এড়িয়ে যায় check
আশ্বিন অগ্রবাল

এখানে সমস্যাটি হ'ল ডাউন স্ট্রিমগুলি সেট করা আছে। যদি আসল কাজগুলি ছাড়াই ডাউনস্ট্রিমগুলি সেট করা থাকে (কারণ কোনও ফাইল নেই) তবে এটি ত্রুটি করবে।
arcee123
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.