Storytelling with Data
132 subscribers
9 photos
2 links
Download Telegram
Xosh, keling Airflow da DAG larni yaratish turlari haqida va yollari haqida korib chiqamiz.
Biz bilgan dag =Dag() usuli

Agarda buni import qilmasak DAG yaratib olmaymiz.

'''
from airflow import DAG
'''

import qilganimizdan song
'''

dag = DAG(...)

'''

shunaqa tartibda yaratib organganmiz.

lekin bu usul kop code yozishga sabab boladi va ishlashida ham farqi bor keyinroq koramiz. bu haqida toliq.

Aytaylik Task yaratmoqchimiz. Buning uchun Operatorlarni chaqirishimiz kerak boladi.


from airflow.operators.python import PythonOperator




task_1 = PythonOperator(
task_id='task_1',
dag=dag, # DAG ga boglashimiz uchun shu parametr kerak har doim.
...
)

Lekin har bir yangi taskda dag=dag parametrini har safar 100 ta task yozsak 100 marta yozish kerak boladi.



task_2 = PythonOperator(
task_id='task_2',
dag=dag, # Buni yana yozish kerak
...
)

task_3 = PythonOperator(
task_id='task_3',
dag=dag, # Yana, yana
...
)



Biz shuni yozmasdan dag yaratishni organamiz 😁

Context Manager - with operator



with DAG(...) as dag:
task_1 = PythonOperator(task_id='task_1', ...)
task_2 = PythonOperator(task_id='task_2', ...)
task_3 = PythonOperator(task_id='task_3', ...)




Bu usul ancha qulay va code quyidagicha boladi
Bu usulda dag=dag ni qayta-qayta yozish shart emas

yana bir usul bor lekin



Uchinchi USulda biz

DAG dekoretorini korib chiqamiz:



from airflow.decorators import dag, task

@dag(...)
def my_dag():
@task
def task_1():
...

@task
def task_2():
...

task_1() >> task_2()

my_dag()





Bu usul with DAG(...) as dag: dan ham yaxshiroq, chunki Airflow keyinchalik dekorator usulini toliq qollab-quvvatlashi kutilmoqda.


Bundan tashqari, @task dekoratori ham mavjud bo‘lib, u PythonOperator ni almashtiradi.

DAG dekoratori (@dag) tavsiya qila olaman, chunki Airflow shu yonalishda rivojlanmoqda. Bundan tashqari, @task dekoratori orqali vazifalarni ham aniqlashtira oladi, bu esa kodni ancha clean code qiladi.

Ammo with DAG(...) usuli ham yaxshi, faqat eski dag=dag usulidan foydalanish tavsiya qilmayman lekin hamma usulni bilib qoygan yaxshi sababi interviewda sorab qolishadi
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Bugun Dag yaratgandagi parametrlar haqida korib chiqamiz va nega kerak degan savollarga javob olamiz!

“start_date” parametri bu dag qachondan boshlab ishga tushishini reja qigan bolamiz.
DateTime obyektiga tenglab belgilaymiz.

Buning uchun bizga pendulum kutubxonasidan DateTime obyektini import qilishimiz kerak boladi.


from pendulum import DateTime


xosh dag qachondan boshlab ishlashini reja qildik endi har qanchada yani 1 kunda yoki har soatda ishlasinmi degan savolga
bu “schedule” parametri orqali javob beramiz!

Masalan, biz bu yerda “schedule” ni “daily” (kunlik) deb belgilab, 2025-yil 1-yanvardan boshlab har kuni yarim tunda ishga tushishini aytaganmiz odatda ozi kechasi 12 am da ishga tushadi.
buni vaqtini aniq ayta olamiz.

bizga kerakli 3 chi parametr bu
catchup hisoblanadi.

Odatda, biz catchup ga false value beramiz chunki ozi default u true holatda boladi.

xop 2025- yil 1-yanvardan keyin bizni projectda xatolik tufayli muvaffaqiyatsiz ishga tushgan daglar bor. agarda catchup True bolsa dag default ularni boshidan yana 1- yanvardan boshlab run berishga try qiladi.


description bu keyingi parametr biz bu yerda
Dag ni yozganmiz va nimaga kerak ekanligini yozib qoya olamiz keyin esa biz airflow ui da kora olishlari uchun code oqib tushunish shart bolmay qoladi.

tags bu parametr bolsa
juda foydali hisoblanadi asosan jamoalar bolib ishlaganda Daglar orasida filtr qoyish uchun.
Biz tags ni qanday tanlashimiz ozimizga bogliqva uni UI da ularni filtrlay olamiz shuning uchun ular juda qulay hisoblanadi.

Keyingi parametr – bu default arguments.
default_args bu dictionary shaklida boladi.

Agar biz Dagdagi barcha tasklar uchun qayta urinib korishlar sonini(retries) belgilamoqchi bolsak, default args ni ishlatishimiz kerak.

masalan
har bir taskni oldiga alohida “retries = 1” deb yozmasdan default_args ga yozib qoyishimizni ozi yetarli boladi.


dagrun_timeout bu bizga agarda dag ni ishlash vaqt oraligi masalan hozirgi vaziyatda agarda dag 20 minut ichida yani boshlangandan 20 minut ichida yakunlamasa avtomatik bu failed boladi degani. bu juda kerakli hisoblanadi.


va oxirgisi max_consecutive_failed_dag_runs
masalan, qiymatini 2 deb belgiladik.

Bu parametr orqali biz, agar dagimiz ketma-ket ikki marta failed bajarilsa, Airflow Dagning keyingi ishga tushirilishini toxtatishi kerakligini belgilaymiz.

Bu juda kerakli, chunki bu Dagning kop marta failed ishga tushirilishini oldini oladi chunki dam olish kunlarida xatoliklar yuz bersa yoki biror sababga kora Dagni post qila olmagan bolsak, yoki juda tez-tez(hourly) ishlaydigan Dag bolsa
kop marta failed ishga tushirilish sonini kamaytiramiz.

bu yerda DAG yaratish uchun kerak bolgan asosiy parametrlarni korib chiqdik.
❤1👍1
backfill
bu mexanizm malumotlaringizni qayta toldirish uchun Dag ishga tushirilgan sanalarni qayta ishga tushirishimiz kerak bolsa yoki boshlanish sanasidan oldingi sanalar uchun dag ishlashi kerak bolganda ishlatamiz.

xosh bizning pipeline larda hammasi yaxshi va ishlab turibdi.
2024-yil 2-yanvardan emas 2024-yil 1-yanvardan ishga tushirishni xohlagan edik.shu vaziyda foydalansak boladi.

Backfilling Airflow tomonidan avtomatik ravishda bajariladigan mexanizm emas.
Uni qolda, terminalda yoki airflow ui orqali ishga tushirishimiz mumkin.
❤2🔥2💩2
CROSS- COMMUNICATION between Tasks in AIRFLOW
(AIRFLOW XCOMS)

xcom - bu tasklar orasida malumot almashish uchun ishlatiladigan mexanizm.
U quyidagi qismlardan iborat:
key (kalit nomi)
value (almashilayotgan ma’lumot)
task_id (ma’lumotni yuborgan task)
dag_id (task qaysi DAGga tegishli)
execution_date (qaysi data interval uchun bajarilgan)

XCOM qiymati odatda JSON formatga serialize qilinadi. Bu har qanday obyektlarni emas, faqat JSON bilan mos keladigan turlarni saqlay oladi.
PICKLE istalgan code uchun ishlaydi shu sabab xavfsiz emas.

1.XCOM PUSH qilish

bunda malumotlarni uzatish uchun uni push qilamiz yani bazaga yozamiz



from airflow import DAG
from airflow.decorators import task

with DAG(...) as dag:

@task()
def sender1():
# 'data' key ostida brand qiymatini yuborish
ti.xcom_push(key='data', value={'brand': 'APPLE'})




xuddi shu natijaga return_value orqali push



from airflow import DAG
from airflow.decorators import task

with DAG(...) as dag:

@task()
def sender2():
# 'return_value' keyi avtomatik tarzda ishlatiladi
return {'brand': 'Apple'}



2.Bazadan yuborilgan qiymatni olish




from airflow import DAG
from airflow.decorators import task

with DAG(...) as dag:

@task()
def receiver1():
# sender task'dan 'data' keyidagi qiymatni olish
ti.xcom_pull(task_ids='sender', key='data')





bizda hozir Standart yani default settings bilan XCOM yani:
• key='return_value' bo’ladi
• Aynan shu DAG run ichida
• Ayni bir DAG dan olinadi

lekin Moslashtirib olishimiz ham mumkin:
• Boshqa DAG’dan (dag_id ni korsatib)
• Bir nechta tasklardan (task_ids=['taskA', 'taskB'])
• Oldingi barcha DAG runlardan (include_prior_dates=True bilan)


Bogliqliklar (Dependencies)

XCOM lar implicit (bilvosita) bogliqliklar hosil qiladi.
Agar Task C, Task A yuborgan XCOM ni ishlatsa, ular orasida avtomatik bogliqlik hosil boladi.shuni
Ikki usulda yozish mumkin:

1.Graph strukturasi orqali

sender() >> receiver()


2.Argument orqali uzatish




receiver(sender())



XCOM Size Limitations (Hajm Cheklovlari )

XCOM qiymatlari bazada saqlanadi shuning uchun hajm cheklovlari mavjud:
SQLite: 2 GB
PostgreSQL: 1 GB
MySQL: 64 MB


demak biz XCOM qiymatlarni saqlashimiz togrimi ???
❤2💯1
Airflow 3.0 chiqarildi!
💋3
Apache Airflow da operatorlarning vazifasi bu DAG ichida bajariladigan individual tasklarni yani har bir dagimiz aynan vazifasini tasniflab beradi. Har bir operator malum bir turdagi ishni bajarish uchun yaratilgan. hozir asosiy operatorlar, farqlari, va qachon ishlatilishi haqida toliq organib chiqsak

PythonOperator
Python kodi bajaradi — yani def bilan yozilgan funksiyani chaqiradi.sodda qilib aytganda
Qachon ishlatiladi:
Har qanday Python kodi bajarmoqchi bolsak (API chaqirish, fayllarni oqish, pandas bilan ishlash)
Malumotlarni qayta ishlash, logika yozish

PythonOperator(
task_id='process_data',
python_callable=process_function
)


BashOperator
Terminal/Shell buyruqlarini bajaradi.
Qachon ishlatiladi:
• Fayl nusxalash, script ishlatish, curl, ls, mv, echo kabi komandalarni chaqirish uchun



BashOperator(
task_id='print_date',
bash_command='date'
)



DummyOperator
Hech qanday ish bajarmaydi — faqat DAG strukturasi uchun kerak.
• DAG ni bo lish
• Branching yoki parallel tasklar uchun “pass-through” nuqta sifatida


DummyOperator(task_id='start')

BranchPythonOperator
Shartli ravishda qaysi task ni bajarish kerakligini hal qiladi.

Qachon ishlatiladi:
• Agar if/else logikasi kerak bolsa
• Masalan: foydalanuvchi turi premium bolsa boshqa yoldan borish



BranchPythonOperator(
task_id='check_type',
python_callable=check_user_type
)



ShortCircuitOperator
Shart False bolsa, davomdagi tasklarni SKIP qiladi.
Qachon ishlatiladi:
• Agar shart bajarilmasa, qolgan tasklar befoyda bolsa


ShortCircuitOperator(
task_id='continue_if_true',
python_callable=check_condition
)

EmailOperator
Email yuboradi.(SMTP conn ID kerak)
Suggestion: trigger_rule='all_failed' yoki on_failure_callback bilan boglab, faqat xato bolsagina jonating.
Qachon ishlatiladi:
• Task muvaffaqiyatli bajarilsa yoki xatolik bilan tugaganda email yuborish


EmailOperator(
task_id='send_email',
to='you@example.com',
subject='Task Done',
html_content='Task finished'
)

TriggerDagRunOperator
Boshqa DAG ni ishga tushuradi.(cross-DAG triggering).
Eng muhim parametrlar: poke_interval, timeout, mode (poke vs reschedule).
Qachon ishlatiladi:
• DAG ichidan boshqa DAG ni boshlash kerak bolsa


TriggerDagRunOperator(
task_id='trigger_other_dag',
trigger_dag_id='another_dag'
)

Sensor Operators (FileSensor, S3KeySensor, HttpSensor . . .)
Malum bir voqeani kutadi (file mavjudligi, API mavjudligi ... )
Qachon ishlatiladi:
• Faylni kutish
• Tizimda malumot tayyor bolishini kutish


FileSensor(
task_id='wait_for_file',
filepath='/data/file.csv',
poke_interval=60
)

DockerOperator
Docker konteyner ichida task bajaradi.
Qachon ishlatiladi:
• Izolyatsiya qilish kerak bolsa
• Har xil muhitda skriptlar ishga tushirilsa

from airflow.providers.docker.operators.docker import DockerOperator

run_etl = DockerOperator(
task_id='run_etl',
image='myrepo/etl:1.2.0',
command='python etl.py --date {{ ds }}',
auto_remove=True,
mounts=['/opt/airflow/data:/data'],
mem_limit='1g',
dag=dag
)



Etiborli bolishimiz kk
• Worker da Docker daemon bolishi shart → resurs istemoli kk boladi
• Image pull → start up kechikishi mm
• Root user konteyneri xavfsizlika ehtiyor bolishimiz kk
• mem_limit, cpu_shares qoyish va XCom ni JSON matn sifatida qaytarish kk boladi

KubernetesPodOperator
Kubernetes cluster da pod yaratib, task bajaradi.
Qachon ishlatiladi:
• Airflow Kubernetes da bolsa
• Katta hajmli, tarqoq hisob-kitoblar uchun

RBAC/ServiceAccount ni togirlash qiyinroq ehtiyot bolishimiz kerak
Koplab mayda podlar paydo bolishi mumkin.
scheduler/etcd ga koproq bosim berishimiz mumkin boladi
Pod startup delay ham bor albatta!

Bu operatorlar eng kop ishlatiladigan Operatorlar va ularning use case larini korib chiqdik!
Keep learning and keep growing.
👍3❤2
from airflow.providers.cncf.kubernetes.operators.kubernetes_pod import KubernetesPodOperator
train = KubernetesPodOperator(
task_id='train_model',
name='train-model-{{ ds_nodash }}',
namespace='airflow',
image='myrepo/ml-train:1.0.0',
cmds=['python', 'train.py'],
arguments=['--epochs', '20'],
resources={'request_memory': '2Gi', 'request_cpu': '1000m'},
get_logs=True,
is_delete_operator_pod=True
)
❤2
Loading – bu malumotlarni source dan target (odatda data warehouse yoki operational database) ga yuklash jarayoni.
1.Full Load
Har safar pipeline ishlaganda butun boshli jadvalni tozalab, barcha malumotlarni toliq qaytadan yuklaymiz.
Target database dagi malumotni ochiradi va qayta yuklaydi har safar(TRUNCATE yoki DELETE)
Yangi malumotlarning hammasini qayta yuklaydi

TRUNCATE TABLE customers;
INSERT INTO customers
SELECT * FROM staging.customers;

2.Incremental Load

Faqat yangi qoshilgan yoki ozgargan rowslar yuklanadi.
Oxirgi yuklangan timestamp (yoki ID) ni saqlab qoladi.Odatda timestamp bn ishlaydi
Faqat yangi (created_at) yoki ozgargan (updated_at) malumotlarni yuklaydi


-- Oxirgi yuklangan sana saqlanadi
SELECT * FROM source_table
WHERE updated_at > '2025-04-27 23:59:59';


3.Delta Load (Change Data Capture - CDC)

Faqat haqiqatan ozgargan, yangi qoshilgan, ochirilgan yozuvlarni aniqlab yuklash.
har bir table da insert update delete larni kuzatib turadi.

OLTP (operational) database dan real-time replikatsiya qilinganda
No-SQL yoki Message queue bilan integratsiyada

Source Database -> Change Logs -> Kafka -> Sink Database
misol structure shunaqa formatda boladi.

4.Streaming Load

data lar real-time yoki kichik intervalda (micro-batch) doimiy yuklanib turadi.



from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("streaming_app").getOrCreate()
df = spark.readStream.format("kafka").option("kafka.bootstrap.servers", "localhost:9092").option("subscribe", "topic_name").load()
🔥3🤯2❤1
PostgreSQL (Source) -> TRUNCATE (old table) -> Load all rows → MS SQL (Target)



from airflow import DAG
from airflow.providers.postgres.operators.postgres import PostgresOperator
from airflow.providers.microsoft.mssql.operators.mssql import MsSqlOperator
from datetime import datetime

with DAG(dag_id="full_load_customers",
start_date=datetime(2024, 1, 1),
schedule_interval="@daily",
catchup=False) as dag:

truncate_target_table = MsSqlOperator(
task_id='truncate_target_table',
mssql_conn_id='mssql_target',
sql="TRUNCATE TABLE customers;"
)

load_full_data = PostgresOperator(
task_id='load_full_data',
postgres_conn_id='postgres_source',
sql="""
INSERT INTO mssql_target.dbo.customers
SELECT * FROM postgres_source.public.customers;
"""
)

truncate_target_table >> load_full_data
🔥1
Forwarded from murodalidev /> (Murodali)
Pythonic nima degani?

Kop joylarda bu so'zni uchratamiz lekin kop e'tiborimizni qaratmaymiz shu haqida qisqacha gapirib bermoqchiman.

"Pythonic" — bu Python tilining ruhiga mos, chiroyli, toza va samarali tarzda yozilgan kod degani. Ya’ni, Python tilining falsafasiga mos keladigan uslubda kod yozish. O'qilishi oson, tabiiy, qisqa, lekin kuchli kod.

Life is short, use Python.

ps: Kodlaringiz doim Pythonic bo'lsin

@murodalidev ✅
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
Forwarded from Thoughts and Knowledge
NoSQL so'zi qanday kelib chiqanini bilasizmi?

NoSQL birinchi Marta twitterdagi hashtag sifatida 2010 yilda foydalanilgan #NoSQL yani u paytda SQL databaza sifatida dominantlik qilib kelgan va SQLga yo'q deymiz degan manoda yozilgan . Ammo u keyinchali o'zgartirilib yani Not Only SQL deb kengaytirilgan va hozirda shu manoda qo'llanilib kelinadi.
❤5
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9❤2👏2
Python da context managerni with kalit sozi bilan ishlatilishidan tanib olsa boladi.
U resurslarni ikkita metod yordamida boshqaradi: __enter__() — resurslarni ishga tayyorlash uchun, __exit__() esa ularni boshatish yoki yopish uchun ishlatiladi.

Context manager xatolik yuz berganda ham resurslar xavfsiz boshqarilishini taminlaydi va odatda fayllar, thread lar yoki malumotlar bazasi ulanishlarini boshqarishda qollaniladi
👍7🔥1
Even though the term big is used in big data, it’s not just about the size of
the data. It’s also about all the data, big or small, within your company and
all the data outside your company that would be helpful to you. The data
can be in any format and can be collected with any degree of regularity.
So the best way to define big data is to think of it as all data,
no matter its size (volume), speed (velocity), or type (variety). In addition to those criteria,
there are three more factors you can use to describe data: veracity,
variability, and value. Together, they’re commonly known as the “six Vs” of
big data
🔥6❤4🏆2
Data Maturity
❤4🔥3👍2⚡1
Modern data warehouse
🔥6👍3⚡1
DuckDB 2.0

Async I/O: S3 dan o’qish 2–3 barobar tezlashdi
Oldin har bir thread navbatma-navbat ishlardi: avval ma’lumotni yuklab olardi, keyin decode qilardi. Natijada CPU tarmoqni kutib bo’sh turardi.

Endi alohida pool row group’larni oldindan tortib qo’yadi, worker’lar esa faqat decode bilan band. 2,2 GB Parquet ustidagi query: 18,8 s → 7,7 s. Default holatda yoqilgan, kodga tegish shart emas (read_ahead_depth). Lekin 1 MB lik minglab mayda fayllaringiz bo’lsa, bu yordam bermaydi, asos baribir to’g’ri qurilgan bo’lishi kerak.

Rekursiv CTE: chuqur ierarxiyalar endi uchib ishlaydi
Oldin rekursiyaning har bir qadamida jadval boshidan oxirigacha qayta o’qilardi. Endi u bir marta o’qiladi, keyin faqat kerakli joylardan lookup qilinadi.

20 000 ta commit’lik tarixni aylanib chiqish oldin 1,8–16 soniya olardi, endi 0,1 soniya. Git tarixi, lineage, thread’lar va BOM uchun ayni muddao. Oddiy, sayoz org-strukturada esa farqni deyarli sezmaysiz.

JSON o’rniga VARIANT
Strukturasi o’zgarmaydigan JSON field’lar avtomatik ravishda alohida kolonkalarga ajratiladi (shredding), qolgani esa binary ko’rinishda saqlanadi.

Natija: JSON string’ga qaraganda 2,7 barobar kam joy, filterlar esa ~6 barobar tez, deyarli oddiy typed kolonkalardek.

Bitta nyuans bor: list larni cast qilish hozircha sekin, bazida son, bazida string bo’lib keladigan field esa kolonkaga ajratilmaydi.
🔥4❤3