āĻšāĻžāĻ, āĻāĻŽāĻŋ āĻĻāĻŋāĻŽāĻŋāĻ¤ā§āĻ°āĻŋ āĻ˛āĻāĻāĻŋāĻ¨ā§āĻā§āĻā§ - āĻā§āĻā§āĻ āĻā§āĻ°ā§āĻĒ āĻ āĻĢ āĻā§āĻŽā§āĻĒāĻžāĻ¨āĻŋāĻ° āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻŖ āĻŦāĻŋāĻāĻžāĻā§āĻ° āĻĄā§āĻāĻž āĻāĻā§āĻāĻŋāĻ¨āĻŋāĻ¯āĻŧāĻžāĻ°āĨ¤
āĻāĻŽāĻŋ āĻāĻĒāĻ¨āĻžāĻā§ ETL āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ˛āĻŋ āĻŦāĻŋāĻāĻžāĻļā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻĻā§āĻ°ā§āĻĻāĻžāĻ¨ā§āĻ¤ āĻ¸āĻ°āĻā§āĻāĻžāĻŽ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻŦāĻ˛āĻŦ - āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĨ¤ āĻ¤āĻŦā§ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻ¤āĻ āĻŦāĻšā§āĻŽā§āĻā§ āĻāĻŦāĻ āĻŦāĻšā§āĻŽā§āĻā§ āĻ¯ā§ āĻāĻĒāĻ¨āĻŋ āĻĄā§āĻāĻž āĻĒā§āĻ°āĻŦāĻžāĻšā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻĄāĻŧāĻŋāĻ¤ āĻ¨āĻž āĻšāĻ˛ā§āĻ āĻāĻāĻŋāĻā§ āĻāĻ°āĻ āĻāĻ¨āĻŋāĻˇā§āĻ āĻāĻžāĻŦā§ āĻĻā§āĻā§ āĻ¨ā§āĻāĻ¯āĻŧāĻž āĻāĻāĻŋāĻ¤, āĻ¤āĻŦā§ āĻĒāĻ°ā§āĻ¯āĻžāĻ¯āĻŧāĻā§āĻ°āĻŽā§ āĻ¯ā§ āĻā§āĻ¨āĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻžāĻ˛ā§ āĻāĻ°āĻž āĻāĻŦāĻ āĻ¤āĻžāĻĻā§āĻ° āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ āĻ¨āĻŋāĻ°ā§āĻā§āĻˇāĻŖ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤
āĻāĻŦāĻ āĻšā§āĻ¯āĻžāĻ, āĻāĻŽāĻŋ āĻā§āĻŦāĻ˛ āĻŦāĻ˛āĻŦ āĻ¨āĻž, āĻ¤āĻŦā§ āĻĻā§āĻāĻžāĻŦ: āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻāĻŋāĻ¤ā§ āĻĒā§āĻ°āĻā§āĻ° āĻā§āĻĄ, āĻ¸ā§āĻā§āĻ°āĻŋāĻ¨āĻļāĻ āĻāĻŦāĻ āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤
āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ / āĻāĻāĻāĻŋāĻŽāĻŋāĻĄāĻŋāĻ¯āĻŧāĻž āĻāĻŽāĻ¨ā§āĻ¸ āĻļāĻŦā§āĻĻāĻāĻŋ āĻā§āĻāĻ˛ āĻāĻ°āĻ˛ā§ āĻāĻĒāĻ¨āĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻ¤ āĻ¯āĻž āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻ¨
āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§ āĻ¸ā§āĻāĻŋ
āĻā§āĻŽāĻŋāĻāĻž āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻ āĻāĻļ, āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻŋāĻ (āĻāĻŦāĻ āĻāĻāĻā§ āĻ¤āĻžāĻ¤ā§āĻ¤ā§āĻŦāĻŋāĻ) āĻā§āĻ¨ āĻāĻŽāĻ°āĻž (āĻāĻŦāĻ āĻāĻĒāĻ¨āĻŋ) āĻā§āĻ˛āĻžāĻ¸ā§āĻāĻžāĻ° āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°āĻž āĻŽā§āĻ˛āĻŋāĻ āĻ§āĻžāĻ°āĻŖāĻž āĻāĻŽāĻ°āĻž āĻāĻžāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋ āĻĢā§āĻ˛ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻāĻā§ āĻāĻŽāĻ°āĻž underloaded āĻ˛ā§āĻĄ āĻ¸āĻāĻ¯ā§āĻ, āĻšā§āĻ āĻāĻŦāĻ āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ āĻāĻžāĻ¸ā§āĻāĻŽ āĻ āĻĒāĻžāĻ°ā§āĻāĻ° āĻĒāĻžāĻ°ā§āĻ¸āĻŋāĻ āĻāĻĒāĻ¨āĻŋ āĻĸāĻžāĻ˛āĻž āĻ¯āĻžāĻā§āĻā§āĻ¨? āĻŦā§āĻĻā§āĻ§āĻŋāĻŽāĻžāĻ¨
āĻĒāĻžāĻ°ā§āĻ āĻĢāĻžāĻāĻ¨āĻžāĻ˛, āĻ°ā§āĻĢāĻžāĻ°ā§āĻ¨ā§āĻ¸ āĻāĻŦāĻ āĻ¤āĻĨā§āĻ¯ āĻ°ā§āĻĢāĻžāĻ°ā§āĻ¨ā§āĻ¸
āĻā§āĻŽāĻŋāĻāĻž
āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ āĻŋāĻ āĻā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻŽāĻ¤ā§:
- āĻĒāĻžāĻāĻĨāĻ¨ā§ āĻ˛ā§āĻāĻž
- āĻāĻāĻāĻŋ āĻŽāĻšāĻžāĻ¨ āĻ ā§āĻ¯āĻžāĻĄāĻŽāĻŋāĻ¨ āĻĒā§āĻ¯āĻžāĻ¨ā§āĻ˛ āĻāĻā§,
- āĻ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻāĻāĻžāĻ˛ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŖāĻ¯ā§āĻā§āĻ¯
- āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻāĻžāĻ˛, āĻāĻŦāĻ āĻāĻāĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻāĻŋāĻ¨ā§āĻ¨ āĻāĻĻā§āĻĻā§āĻļā§āĻ¯ā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛, āĻ¯āĻĨāĻž (āĻ¯ā§āĻŽāĻ¨ āĻāĻāĻŋ āĻā§āĻ¯āĻžāĻā§āĻ° āĻāĻā§ āĻ˛ā§āĻāĻž āĻāĻā§):
- āĻ¸ā§āĻŽāĻžāĻšā§āĻ¨ āĻ¸āĻāĻā§āĻ¯āĻ āĻŽā§āĻļāĻŋāĻ¨ā§ āĻāĻžāĻ āĻāĻžāĻ˛āĻžāĻ¨ā§ āĻāĻŦāĻ āĻĒāĻ°ā§āĻ¯āĻŦā§āĻā§āĻˇāĻŖ āĻāĻ°āĻž (āĻ¯āĻ¤ āĻŦā§āĻļāĻŋ āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ/āĻā§āĻŦāĻžāĻ°āĻ¨ā§āĻāĻ¸ āĻāĻŦāĻ āĻāĻĒāĻ¨āĻžāĻ° āĻŦāĻŋāĻŦā§āĻ āĻāĻĒāĻ¨āĻžāĻā§ āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻŦā§)
- āĻĄāĻžāĻ¯āĻŧāĻ¨āĻžāĻŽāĻŋāĻ āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻĢā§āĻ˛ā§ āĻā§āĻ¨āĻžāĻ°ā§āĻļāĻ¨ā§āĻ° āĻ¸āĻžāĻĨā§ āĻĒāĻžāĻāĻĨāĻ¨ āĻā§āĻĄ āĻ˛āĻŋāĻāĻ¤ā§ āĻāĻŦāĻ āĻŦā§āĻāĻ¤ā§ āĻā§āĻŦ āĻ¸āĻšāĻ āĻĨā§āĻā§
- āĻāĻŦāĻ āĻ°ā§āĻĄāĻŋāĻŽā§āĻĄ āĻāĻŽā§āĻĒā§āĻ¨ā§āĻ¨ā§āĻ āĻāĻŦāĻ āĻāĻ°ā§ āĻ¤ā§āĻ°āĻŋ āĻĒā§āĻ˛āĻžāĻāĻāĻ¨ āĻāĻāĻ¯āĻŧ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¯ā§āĻā§āĻ¨ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻāĻŦāĻ āĻāĻĒāĻŋāĻāĻ āĻāĻā§ āĻ āĻĒāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻāĻ¯ā§āĻ āĻāĻ°āĻžāĻ° āĻā§āĻˇāĻŽāĻ¤āĻž (āĻ¯āĻž āĻ āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¸āĻšāĻ)āĨ¤
āĻāĻŽāĻ°āĻž āĻāĻ āĻŽāĻ¤ Apache Airflow āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŋ:
- āĻāĻŽāĻ°āĻž āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻā§āĻ¸ āĻĨā§āĻā§ āĻĄā§āĻāĻž āĻ¸āĻāĻā§āĻ°āĻš āĻāĻ°āĻŋ (āĻ āĻ¨ā§āĻ SQL āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻāĻŦāĻ PostgreSQL āĻāĻĻāĻžāĻšāĻ°āĻŖ, āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ āĻŽā§āĻā§āĻ°āĻŋāĻā§āĻ¸ āĻ¸āĻš āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ API, āĻāĻŽāĻ¨āĻāĻŋ 1C) DWH āĻāĻŦāĻ ODS (āĻāĻŽāĻžāĻĻā§āĻ° Vertica āĻāĻŦāĻ Clickhouse āĻāĻā§)āĨ¤
- āĻāĻ¤ āĻāĻ¨ā§āĻ¨āĻ¤
cron
, āĻ¯āĻž āĻāĻĄāĻŋāĻāĻ¸-āĻ āĻĄā§āĻāĻž āĻāĻāĻ¤ā§āĻ°ā§āĻāĻ°āĻŖ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻļā§āĻ°ā§ āĻāĻ°ā§ āĻāĻŦāĻ āĻ¤āĻžāĻĻā§āĻ° āĻ°āĻā§āĻˇāĻŖāĻžāĻŦā§āĻā§āĻˇāĻŖāĻ āĻĒāĻ°ā§āĻ¯āĻŦā§āĻā§āĻˇāĻŖ āĻāĻ°ā§āĨ¤
āĻ¸āĻŽā§āĻĒā§āĻ°āĻ¤āĻŋ āĻ āĻŦāĻ§āĻŋ, āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻžāĻšāĻŋāĻĻāĻžāĻā§āĻ˛āĻŋ 32 āĻā§āĻ° āĻāĻŦāĻ 50 GB RAM āĻ¸āĻš āĻāĻāĻāĻŋ āĻā§āĻ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻāĻā§āĻāĻžāĻĻāĻŋāĻ¤ āĻāĻŋāĻ˛ā§ˇ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĻ¤ā§, āĻāĻāĻŋ āĻāĻžāĻ āĻāĻ°ā§:
- āĻ āĻ§āĻŋāĻ 200 āĻĄā§āĻ¯āĻžāĻ (āĻāĻ¸āĻ˛ā§ āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻĢā§āĻ˛ā§, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻāĻŽāĻ°āĻž āĻāĻžāĻāĻā§āĻ˛āĻŋ āĻ¸ā§āĻāĻžāĻĢ āĻāĻ°ā§āĻāĻŋ)
- āĻāĻĄāĻŧā§ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋāĻ¤ā§ 70āĻāĻŋ āĻāĻžāĻ,
- āĻāĻ āĻ§āĻžāĻ°ā§āĻŽāĻŋāĻāĻ¤āĻž āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧ (āĻāĻĄāĻŧā§āĻ) āĻāĻ¨ā§āĻāĻžāĻ¯āĻŧ āĻāĻāĻŦāĻžāĻ°.
āĻāĻŦāĻ āĻāĻŽāĻ°āĻž āĻā§āĻāĻžāĻŦā§ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŋāĻ¤ āĻāĻ°ā§āĻāĻŋ āĻ¸ā§ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§, āĻāĻŽāĻŋ āĻ¨ā§āĻā§ āĻ˛āĻŋāĻāĻŦ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨ āĻāĻ¸ā§āĻ¨ Ãŧber-āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻāĻŋ āĻ¸āĻāĻā§āĻāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻāĻ°āĻŋ āĻ¯āĻž āĻāĻŽāĻ°āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻāĻ°āĻŦ:
āĻ¤āĻŋāĻ¨āĻāĻŋ āĻā§āĻ¸ āĻāĻ¸āĻāĻŋāĻāĻāĻ˛ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻ°āĻ¯āĻŧā§āĻā§, āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋāĻ¤ā§ 50āĻāĻŋ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻ°āĻ¯āĻŧā§āĻā§ - āĻ¯āĻĨāĻžāĻā§āĻ°āĻŽā§ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻāĻ˛ā§āĻĒā§āĻ° āĻāĻĻāĻžāĻšāĻ°āĻŖ, āĻ¤āĻžāĻĻā§āĻ° āĻāĻāĻ āĻāĻžāĻ āĻžāĻŽā§ āĻ°āĻ¯āĻŧā§āĻā§ (āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ¸āĻ°ā§āĻŦāĻ¤ā§āĻ°, āĻŽā§āĻ-āĻšāĻž-āĻšāĻž), āĻ¯āĻžāĻ° āĻ āĻ°ā§āĻĨ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋāĻ¤ā§ āĻāĻāĻāĻŋ āĻ āĻ°ā§āĻĄāĻžāĻ° āĻā§āĻŦāĻŋāĻ˛ āĻ°āĻ¯āĻŧā§āĻā§ (āĻ¸ā§āĻāĻžāĻā§āĻ¯āĻā§āĻ°āĻŽā§, āĻāĻāĻŋ āĻ¸āĻš āĻāĻāĻāĻŋ āĻā§āĻŦāĻŋāĻ˛ āĻ¨āĻžāĻŽ āĻ¯ā§āĻā§āĻ¨ āĻŦā§āĻ¯āĻŦāĻ¸āĻžāĻ¯āĻŧ āĻĒā§āĻļ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§)āĨ¤ āĻāĻŽāĻ°āĻž āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°āĻā§āĻ˛āĻŋ (āĻ¸ā§āĻ°ā§āĻ¸ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°, āĻ¸ā§āĻ°ā§āĻ¸ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸, ETL āĻāĻžāĻ¸ā§āĻ āĻāĻāĻĄāĻŋ) āĻ¯ā§āĻ āĻāĻ°ā§ āĻĄā§āĻāĻž āĻ¨āĻŋāĻ¯āĻŧā§ āĻĨāĻžāĻāĻŋ āĻāĻŦāĻ āĻ¸āĻšāĻā§ āĻ¸ā§āĻā§āĻ˛āĻŋāĻā§ āĻāĻžāĻ°ā§āĻāĻŋāĻāĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĢā§āĻ˛ā§ āĻĻāĻŋāĻāĨ¤
āĻāĻ˛ āĻ¯āĻžāĻ!
āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻ āĻāĻļ, āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻŋāĻ (āĻāĻŦāĻ āĻāĻāĻā§ āĻ¤āĻžāĻ¤ā§āĻ¤ā§āĻŦāĻŋāĻ)
āĻā§āĻ¨ āĻāĻŽāĻ°āĻž (āĻāĻŦāĻ āĻāĻĒāĻ¨āĻŋ)
āĻ¯āĻāĻ¨ āĻāĻžāĻāĻā§āĻ˛ā§ āĻŦāĻĄāĻŧ āĻāĻŋāĻ˛ āĻāĻ° āĻāĻŽāĻŋ āĻ¸āĻ°āĻ˛ āĻāĻŋāĻ˛āĻžāĻŽ SQL
-āĻāĻāĻāĻŋ āĻ°āĻžāĻļāĻŋāĻ¯āĻŧāĻžāĻ¨ āĻā§āĻāĻ°ā§āĻ¤ā§, āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻžāĻā§ āĻāĻĒāĻ˛āĻŦā§āĻ§ āĻĻā§āĻāĻŋ āĻ¸āĻ°āĻā§āĻāĻžāĻŽ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ ETL āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻ°āĻĢā§ āĻĄā§āĻāĻž āĻĒā§āĻ°āĻŦāĻžāĻšāĻā§ āĻ¸ā§āĻā§āĻ¯āĻžāĻŽ āĻāĻ°ā§āĻāĻŋ:
- āĻāĻ¨āĻĢāĻ°āĻŽā§āĻāĻŋāĻāĻž ââāĻĒāĻžāĻāĻ¯āĻŧāĻžāĻ° āĻ¸ā§āĻ¨ā§āĻāĻžāĻ° - āĻāĻāĻāĻŋ āĻ
āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤ āĻāĻĄāĻŧāĻŋāĻ¯āĻŧā§ āĻĒāĻĄāĻŧāĻž āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ, āĻ
āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤ āĻāĻ¤ā§āĻĒāĻžāĻĻāĻ¨āĻļā§āĻ˛, āĻ¨āĻŋāĻāĻ¸ā§āĻŦ āĻšāĻžāĻ°ā§āĻĄāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ¸āĻš, āĻāĻ° āĻ¨āĻŋāĻāĻ¸ā§āĻŦ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖāĨ¤ āĻāĻŽāĻŋ āĻāĻ° āĻā§āĻˇāĻŽāĻ¤āĻžāĻ° 1% āĻāĻļā§āĻŦāĻ° āĻ¨āĻŋāĻˇā§āĻ§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋāĨ¤ āĻā§āĻ¨? āĻ āĻŋāĻ āĻāĻā§, āĻĒā§āĻ°āĻĨāĻŽāĻ¤, āĻāĻ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸āĻāĻŋ 380 āĻāĻ° āĻĻāĻļāĻā§āĻ° āĻā§āĻĨāĻžāĻ āĻŽāĻžāĻ¨āĻ¸āĻŋāĻāĻāĻžāĻŦā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻĒāĻ° āĻāĻžāĻĒ āĻ¸ā§āĻˇā§āĻāĻŋ āĻāĻ°ā§āĻā§āĨ¤ āĻĻā§āĻŦāĻŋāĻ¤ā§āĻ¯āĻŧāĻ¤, āĻāĻ āĻāĻ¨āĻā§āĻ°āĻžāĻĒāĻļāĻ¨āĻāĻŋ āĻ
āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤ āĻ
āĻāĻŋāĻ¨āĻŦ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž, āĻāĻā§āĻ° āĻāĻĒāĻžāĻĻāĻžāĻ¨ āĻĒā§āĻ¨āĻāĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻŦāĻ āĻ
āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ
āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤-āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ-āĻāĻ¨ā§āĻāĻžāĻ°āĻĒā§āĻ°āĻžāĻāĻ-āĻā§āĻļāĻ˛ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĄāĻŋāĻāĻžāĻāĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻ¯āĻŧāĻžāĻ°āĻŦāĻžāĻ¸ AXNUMX / āĻŦāĻāĻ°ā§āĻ° āĻāĻāĻ āĻāĻ° āĻŽāĻ¤ āĻāĻāĻŋāĻ° āĻĻāĻžāĻŽ āĻā§ āĻ¤āĻž āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻŽāĻ°āĻž āĻāĻŋāĻā§ āĻŦāĻ˛āĻŦ āĻ¨āĻžāĨ¤
āĻ¸āĻžāĻŦāĻ§āĻžāĻ¨, āĻāĻāĻāĻŋ āĻ¸ā§āĻā§āĻ°āĻŋāĻ¨āĻļāĻ 30 āĻŦāĻāĻ°ā§āĻ° āĻāĻŽ āĻŦāĻ¯āĻŧāĻ¸ā§ āĻ˛ā§āĻā§āĻĻā§āĻ° āĻāĻŋāĻā§āĻāĻž āĻā§āĻˇāĻ¤āĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§
- SQL āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻāĻ¨ā§āĻāĻŋāĻā§āĻ°ā§āĻļāĻ¨ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° - āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¤āĻāĻĒā§āĻ°āĻāĻ˛ā§āĻĒ āĻĒā§āĻ°āĻŦāĻžāĻšā§ āĻāĻ āĻāĻŽāĻ°ā§āĻĄ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋāĨ¤ āĻ āĻŋāĻ āĻāĻā§, āĻāĻ¸āĻ˛ā§: āĻāĻŽāĻ°āĻž āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§āĻ SQL āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŋ, āĻāĻŦāĻ āĻāĻāĻŋāĻ° ETL āĻ¸āĻ°āĻā§āĻāĻžāĻŽāĻā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ¨āĻž āĻāĻ°āĻž āĻāĻāĻ°āĻāĻŽ āĻ
āĻ¯ā§āĻā§āĻ¤āĻŋāĻ āĻšāĻŦā§āĨ¤ āĻāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¸āĻŦāĻāĻŋāĻā§āĻ āĻāĻžāĻ˛ā§: āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ āĻĻā§āĻāĻŋāĻ āĻ¸ā§āĻ¨ā§āĻĻāĻ°, āĻāĻŦāĻ āĻ
āĻā§āĻ°āĻāĻ¤āĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻŦā§āĻĻāĻ¨... āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ āĻāĻžāĻ°āĻŖā§āĻ āĻāĻŽāĻ°āĻž āĻ¸āĻĢā§āĻāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻĒāĻŖā§āĻ¯ āĻĒāĻāĻ¨ā§āĻĻ āĻāĻ°āĻŋ āĻ¨āĻž, āĻāĻš, āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻ¯āĻŧāĨ¤ āĻāĻāĻž āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖ
dtsx
(āĻ¯ā§āĻāĻŋ XML āĻ¨ā§āĻĄāĻā§āĻ˛āĻŋāĻā§ āĻ¸ā§āĻ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ˛ā§āĻŽā§āĻ˛ā§ āĻāĻ°ā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧ) āĻāĻŽāĻ°āĻž āĻĒāĻžāĻ°āĻŋ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻā§ āĻ˛āĻžāĻ? āĻā§āĻāĻžāĻŦā§ āĻāĻāĻāĻŋ āĻāĻžāĻ¸ā§āĻ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŦā§āĻ¨ āĻ¯āĻž āĻāĻ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻĨā§āĻā§ āĻ āĻ¨ā§āĻ¯ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§ āĻļāĻ¤ āĻļāĻ¤ āĻā§āĻŦāĻŋāĻ˛ āĻā§āĻ¨ā§ āĻāĻ¨āĻŦā§? āĻšā§āĻ¯āĻžāĻ, āĻāĻŋ āĻāĻāĻļ, āĻāĻĒāĻ¨āĻžāĻ° āĻ¤āĻ°ā§āĻāĻ¨ā§ āĻŦāĻŋāĻļ āĻā§āĻāĻ°āĻž āĻĨā§āĻā§ āĻĒāĻĄāĻŧā§ āĻ¯āĻžāĻŦā§, āĻŽāĻžāĻāĻ¸ āĻŦā§āĻ¤āĻžāĻŽā§ āĻā§āĻ˛āĻŋāĻ āĻāĻ°ā§āĻ¨āĨ¤ āĻ¤āĻŦā§ āĻāĻāĻŋ āĻ āĻŦāĻļā§āĻ¯āĻ āĻāĻ°āĻ āĻĢā§āĻ¯āĻžāĻļāĻ¨ā§āĻŦāĻ˛ āĻĻā§āĻāĻžāĻ¯āĻŧ:
āĻāĻŽāĻ°āĻž āĻ āĻŦāĻļā§āĻ¯āĻ āĻāĻĒāĻžāĻ¯āĻŧ āĻā§āĻāĻāĻāĻŋ. āĻŽāĻžāĻŽāĻ˛āĻž āĻāĻŽāĻ¨āĻāĻŋ āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻāĻāĻāĻŋ āĻ¸ā§āĻŦ-āĻ˛āĻŋāĻāĻŋāĻ¤ SSIS āĻĒā§āĻ¯āĻžāĻā§āĻ āĻā§āĻ¨āĻžāĻ°ā§āĻāĻ°ā§ āĻāĻ¸ā§āĻā§ ...
âĻāĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ° āĻāĻāĻāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻāĻžāĻāĻ°āĻŋ āĻāĻŽāĻžāĻā§ āĻā§āĻāĻā§ āĻĒā§āĻ¯āĻŧā§āĻāĻŋāĻ˛āĨ¤ āĻāĻŦāĻ āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻāĻŋāĻ¤ā§ āĻāĻŽāĻžāĻā§ āĻāĻžāĻĄāĻŧāĻŋāĻ¯āĻŧā§ āĻā§āĻā§āĨ¤
āĻ¯āĻāĻ¨ āĻāĻŽāĻŋ āĻāĻžāĻ¨āĻ¤ā§ āĻĒāĻžāĻ°āĻ˛āĻžāĻŽ āĻ¯ā§ ETL āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻŦāĻŋāĻŦāĻ°āĻŖāĻā§āĻ˛āĻŋ āĻšāĻ˛ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻĒāĻžāĻāĻĨāĻ¨ āĻā§āĻĄ, āĻ¤āĻāĻ¨ āĻāĻŽāĻŋ āĻāĻ¨āĻ¨ā§āĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻžāĻ āĻāĻ°āĻŋāĻ¨āĻŋāĨ¤ āĻāĻāĻžāĻŦā§āĻ āĻĄā§āĻāĻž āĻ¸ā§āĻā§āĻ°āĻŋāĻŽāĻā§āĻ˛āĻŋāĻā§ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ āĻāĻŦāĻ āĻāĻ˛āĻžāĻĻāĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ āĻāĻŦāĻ āĻļāĻ¤ āĻļāĻ¤ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻāĻžāĻ°ā§āĻā§āĻā§ āĻāĻāĻ āĻāĻžāĻ āĻžāĻŽā§āĻ° āĻ¸āĻžāĻĨā§ āĻā§āĻŦāĻŋāĻ˛ āĻĸā§āĻ˛ā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻĻā§āĻĄāĻŧ āĻŦāĻž āĻĻā§āĻ 13â āĻ¸ā§āĻā§āĻ°āĻŋāĻ¨ā§ āĻĒāĻžāĻāĻĨāĻ¨ āĻā§āĻĄā§āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧ āĻšāĻ¯āĻŧā§ āĻĻāĻžāĻāĻĄāĻŧāĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛āĨ¤
āĻā§āĻ˛āĻžāĻ¸ā§āĻāĻžāĻ° āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°āĻž
āĻāĻ¸ā§āĻ¨ āĻāĻāĻāĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻāĻŋāĻ¨ā§āĻĄāĻžāĻ°āĻāĻžāĻ°ā§āĻā§āĻ¨ā§āĻ° āĻŦā§āĻ¯āĻŦāĻ¸ā§āĻĨāĻž āĻāĻ°āĻŋ āĻ¨āĻž, āĻāĻŦāĻ āĻāĻāĻžāĻ¨ā§ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻ¸ā§āĻ¸ā§āĻĒāĻˇā§āĻ āĻāĻŋāĻ¨āĻŋāĻ¸āĻā§āĻ˛āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻĨāĻž āĻŦāĻ˛āĻŋ āĻ¨āĻž, āĻ¯ā§āĻŽāĻ¨ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻž, āĻāĻĒāĻ¨āĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻŋāĻ¤ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸, āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻāĻŦāĻ āĻĄāĻāĻā§āĻ˛āĻŋāĻ¤ā§ āĻŦāĻ°ā§āĻŖāĻŋāĻ¤ āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĨ¤
āĻ¯āĻžāĻ¤ā§ āĻāĻŽāĻ°āĻž āĻ
āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ, āĻāĻŽāĻŋ āĻ¸ā§āĻā§āĻ āĻāĻ°ā§āĻāĻŋ docker-compose.yml
āĻ¯āĻž:
- āĻāĻ° āĻāĻ¸āĻ˛ā§ āĻŦāĻžāĻĄāĻŧāĻžāĻ¤ā§ āĻ¯āĻžāĻ āĻŦāĻžāĻ¤āĻžāĻ¸ā§āĻ° āĻĒā§āĻ°āĻŦāĻžāĻš: āĻļāĻŋāĻĄāĻŋāĻāĻ˛āĻžāĻ°, āĻāĻ¯āĻŧā§āĻŦ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°āĨ¤ āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻāĻžāĻāĻā§āĻ˛āĻŋ āĻ¨āĻŋāĻ°ā§āĻā§āĻˇāĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĢā§āĻ˛ āĻ¸ā§āĻāĻžāĻ¨ā§ āĻā§āĻ°āĻŦā§ (āĻāĻžāĻ°āĻŖ āĻāĻāĻŋ āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§āĻ āĻ ā§āĻ˛ā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧā§āĻā§
apache/airflow:1.10.10-python3.7
āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŽāĻ°āĻž āĻāĻŋāĻā§ āĻŽāĻ¨ā§ āĻāĻ°āĻŋ āĻ¨āĻž) - āĻĒā§āĻ¸ā§āĻāĻā§āĻ°āĻŋ, āĻ¯āĻžāĻ¤ā§ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ¤āĻžāĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻ¤āĻĨā§āĻ¯ āĻ˛āĻŋāĻāĻŦā§ (āĻļāĻŋāĻĄāĻŋāĻāĻ˛āĻžāĻ° āĻĄā§āĻāĻž, āĻāĻā§āĻ¸āĻŋāĻāĻŋāĻāĻļāĻ¨ āĻĒāĻ°āĻŋāĻ¸āĻāĻā§āĻ¯āĻžāĻ¨, āĻāĻ¤ā§āĻ¯āĻžāĻĻāĻŋ), āĻāĻŦāĻ āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻāĻžāĻāĻā§āĻ˛āĻŋ āĻāĻŋāĻšā§āĻ¨āĻŋāĻ¤ āĻāĻ°āĻŦā§;
- Redis, āĻ¯āĻž āĻ¸ā§āĻ˛āĻžāĻ°āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻāĻžāĻ¸ā§āĻ āĻŦā§āĻ°ā§āĻāĻžāĻ° āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻžāĻ āĻāĻ°āĻŦā§;
- āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻāĻ°ā§āĻŽā§, āĻ¯āĻž āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ āĻāĻžāĻ°ā§āĻ¯ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ā§ āĻ¨āĻŋāĻ¯ā§āĻā§āĻ¤ āĻĨāĻžāĻāĻŦā§āĨ¤
- āĻĢā§āĻ˛ā§āĻĄāĻžāĻ°ā§
./dags
āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋāĻā§ āĻĄā§āĻ¯āĻžāĻāĻā§āĻ˛āĻŋāĻ° āĻŦāĻŋāĻŦāĻ°āĻŖā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¯ā§āĻā§āĻ¤ āĻāĻ°āĻŦāĨ¤ āĻāĻā§āĻ˛āĻŋ āĻāĻĄāĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¤ā§āĻ˛ā§ āĻ¨ā§āĻāĻ¯āĻŧāĻž āĻšāĻŦā§, āĻ¤āĻžāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻšāĻžāĻāĻāĻŋāĻ° āĻĒāĻ°ā§ āĻĒā§āĻ°ā§ āĻ¸ā§āĻā§āĻ¯āĻžāĻāĻāĻŋ āĻā§āĻ°āĻžāĻā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻĻāĻ°āĻāĻžāĻ° āĻ¨ā§āĻāĨ¤
āĻāĻŋāĻā§ āĻāĻžāĻ¯āĻŧāĻāĻžāĻ¯āĻŧ, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻā§āĻ˛āĻŋāĻ° āĻā§āĻĄāĻāĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖāĻ°ā§āĻĒā§ āĻĻā§āĻāĻžāĻ¨ā§ āĻšāĻ¯āĻŧ āĻ¨āĻž (āĻ¯āĻžāĻ¤ā§ āĻĒāĻžāĻ ā§āĻ¯āĻāĻŋ āĻŦāĻŋāĻļā§āĻā§āĻāĻ˛ āĻ¨āĻž āĻšāĻ¯āĻŧ), āĻ¤āĻŦā§ āĻā§āĻĨāĻžāĻ āĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ¯āĻŧ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻāĻžāĻā§āĻ° āĻā§āĻĄ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻ¸āĻāĻā§āĻ°āĻšāĻ¸ā§āĻĨāĻ˛ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻŦā§
https://github.com/dm-logv/airflow-tutorial .
Docker-compose.yml
version: '3.4'
x-airflow-config: &airflow-config
AIRFLOW__CORE__DAGS_FOLDER: /dags
AIRFLOW__CORE__EXECUTOR: CeleryExecutor
AIRFLOW__CORE__FERNET_KEY: MJNz36Q8222VOQhBOmBROFrmeSxNOgTCMaVp2_HOtE0=
AIRFLOW__CORE__HOSTNAME_CALLABLE: airflow.utils.net:get_host_ip_address
AIRFLOW__CORE__SQL_ALCHEMY_CONN: postgres+psycopg2://airflow:airflow@airflow-db:5432/airflow
AIRFLOW__CORE__PARALLELISM: 128
AIRFLOW__CORE__DAG_CONCURRENCY: 16
AIRFLOW__CORE__MAX_ACTIVE_RUNS_PER_DAG: 4
AIRFLOW__CORE__LOAD_EXAMPLES: 'False'
AIRFLOW__CORE__LOAD_DEFAULT_CONNECTIONS: 'False'
AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_RETRY: 'False'
AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_FAILURE: 'False'
AIRFLOW__CELERY__BROKER_URL: redis://broker:6379/0
AIRFLOW__CELERY__RESULT_BACKEND: db+postgresql://airflow:airflow@airflow-db/airflow
x-airflow-base: &airflow-base
image: apache/airflow:1.10.10-python3.7
entrypoint: /bin/bash
restart: always
volumes:
- ./dags:/dags
- ./requirements.txt:/requirements.txt
services:
# Redis as a Celery broker
broker:
image: redis:6.0.5-alpine
# DB for the Airflow metadata
airflow-db:
image: postgres:10.13-alpine
environment:
- POSTGRES_USER=airflow
- POSTGRES_PASSWORD=airflow
- POSTGRES_DB=airflow
volumes:
- ./db:/var/lib/postgresql/data
# Main container with Airflow Webserver, Scheduler, Celery Flower
airflow:
<<: *airflow-base
environment:
<<: *airflow-config
AIRFLOW__SCHEDULER__DAG_DIR_LIST_INTERVAL: 30
AIRFLOW__SCHEDULER__CATCHUP_BY_DEFAULT: 'False'
AIRFLOW__SCHEDULER__MAX_THREADS: 8
AIRFLOW__WEBSERVER__LOG_FETCH_TIMEOUT_SEC: 10
depends_on:
- airflow-db
- broker
command: >
-c " sleep 10 &&
pip install --user -r /requirements.txt &&
/entrypoint initdb &&
(/entrypoint webserver &) &&
(/entrypoint flower &) &&
/entrypoint scheduler"
ports:
# Celery Flower
- 5555:5555
# Airflow Webserver
- 8080:8080
# Celery worker, will be scaled using `--scale=n`
worker:
<<: *airflow-base
environment:
<<: *airflow-config
command: >
-c " sleep 10 &&
pip install --user -r /requirements.txt &&
/entrypoint worker"
depends_on:
- airflow
- airflow-db
- broker
āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻ¸āĻŽā§āĻš:
- āĻ°āĻāĻ¨āĻžāĻāĻŋāĻ° āĻ¸āĻŽāĻžāĻŦā§āĻļā§, āĻāĻŽāĻŋ āĻŽā§āĻ˛āĻ¤ āĻ¸ā§āĻĒāĻ°āĻŋāĻāĻŋāĻ¤ āĻāĻŋāĻ¤ā§āĻ°ā§āĻ° āĻāĻĒāĻ° āĻ¨āĻŋāĻ°ā§āĻāĻ° āĻāĻ°ā§āĻāĻŋāĻ˛āĻžāĻŽ
āĻĒāĻžāĻā§āĻ˛/āĻĄāĻāĻžāĻ°-āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ - āĻāĻāĻŋ āĻā§āĻ āĻāĻāĻ āĻāĻ°āĻ¤ā§ āĻā§āĻ˛āĻŦā§āĻ¨ āĻ¨āĻž. āĻšāĻ¯āĻŧāĻ¤ā§ āĻ¤ā§āĻŽāĻžāĻ° āĻā§āĻŦāĻ¨ā§ āĻāĻ° āĻāĻŋāĻā§āĻ° āĻĻāĻ°āĻāĻžāĻ° āĻ¨ā§āĻāĨ¤ - āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ¸ā§āĻāĻŋāĻāĻ¸ āĻ¨āĻž āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻĒāĻ˛āĻŦā§āĻ§
airflow.cfg
, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻĒāĻ°āĻŋāĻŦā§āĻļ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§āĻ (āĻĄā§āĻā§āĻ˛āĻĒāĻžāĻ°āĻĻā§āĻ° āĻ§āĻ¨ā§āĻ¯āĻŦāĻžāĻĻ), āĻ¯āĻž āĻāĻŽāĻŋ āĻĻā§āĻˇāĻŋāĻ¤āĻāĻžāĻŦā§ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĨ¤ - āĻ¸ā§āĻŦāĻžāĻāĻžāĻŦāĻŋāĻāĻāĻžāĻŦā§āĻ, āĻāĻāĻŋ āĻāĻ¤ā§āĻĒāĻžāĻĻāĻ¨-āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤ āĻ¨āĻ¯āĻŧ: āĻāĻŽāĻŋ āĻāĻā§āĻāĻžāĻā§āĻ¤āĻāĻžāĻŦā§ āĻĒāĻžāĻ¤ā§āĻ°ā§ āĻšāĻžāĻ°ā§āĻāĻŦāĻŋāĻ āĻ°āĻžāĻāĻŋāĻ¨āĻŋ, āĻāĻŽāĻŋ āĻ¨āĻŋāĻ°āĻžāĻĒāĻ¤ā§āĻ¤āĻž āĻ¨āĻŋāĻ¯āĻŧā§ āĻŽāĻžāĻĨāĻž āĻāĻžāĻŽāĻžāĻāĻ¨āĻŋāĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŽāĻŋ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻ°ā§āĻā§āĻˇāĻžāĻāĻžāĻ°ā§āĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¨ā§āĻ¯ā§āĻ¨āĻ¤āĻŽ āĻāĻĒāĻ¯ā§āĻā§āĻ¤ āĻāĻ°ā§āĻāĻŋāĨ¤
- āĻŽāĻ¨ā§ āĻ°āĻžāĻāĻŦā§āĻ¨ āĻ¯ā§:
- āĻĄā§āĻ āĻĢā§āĻ˛ā§āĻĄāĻžāĻ°āĻāĻŋ āĻļāĻŋāĻĄāĻŋāĻāĻ˛āĻāĻžāĻ°ā§ āĻāĻŦāĻ āĻāĻ°ā§āĻŽā§āĻĻā§āĻ° āĻāĻāĻ¯āĻŧā§āĻ° āĻāĻžāĻā§āĻ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸āĻ¯ā§āĻā§āĻ¯ āĻšāĻ¤ā§ āĻšāĻŦā§āĨ¤
- āĻāĻāĻ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¤ā§āĻ¤ā§āĻ¯āĻŧ āĻĒāĻā§āĻˇā§āĻ° āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻĒā§āĻ°āĻ¯ā§āĻā§āĻ¯ - āĻ¸ā§āĻā§āĻ˛āĻŋ āĻ āĻŦāĻļā§āĻ¯āĻ āĻāĻāĻāĻŋ āĻļāĻŋāĻĄāĻŋāĻāĻ˛ āĻāĻŦāĻ āĻāĻ°ā§āĻŽā§āĻĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻŽā§āĻļāĻŋāĻ¨ā§ āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻž āĻāĻāĻŋāĻ¤āĨ¤
āĻāĻā§āĻāĻž, āĻāĻāĻ¨ āĻāĻāĻž āĻ¸āĻšāĻ:
$ docker-compose up --scale worker=3
āĻ¸āĻŦāĻāĻŋāĻā§ āĻāĻ āĻžāĻ° āĻĒāĻ°ā§, āĻāĻĒāĻ¨āĻŋ āĻāĻ¯āĻŧā§āĻŦ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸āĻā§āĻ˛āĻŋ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨:
- āĻŦāĻžāĻ¤āĻžāĻ¸ā§āĻ° āĻĒā§āĻ°āĻŦāĻžāĻš:
http://127.0.0.1:8080/admin/ - āĻĢā§āĻ˛āĻžāĻāĻ¯āĻŧāĻžāĻ°:
http://127.0.0.1:5555/dashboard
āĻŽā§āĻ˛āĻŋāĻ āĻ§āĻžāĻ°āĻŖāĻž
āĻāĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻāĻ āĻ¸āĻŽāĻ¸ā§āĻ¤ "āĻĄā§āĻ¯āĻžāĻāĻ¸" āĻāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻŋāĻā§ āĻ¨āĻž āĻŦā§āĻā§ āĻĨāĻžāĻā§āĻ¨ āĻ¤āĻŦā§ āĻāĻāĻžāĻ¨ā§ āĻāĻāĻāĻŋ āĻ¸āĻāĻā§āĻˇāĻŋāĻĒā§āĻ¤ āĻ āĻāĻŋāĻ§āĻžāĻ¨ āĻ°āĻ¯āĻŧā§āĻā§:
- āĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŖāĻāĻžāĻ°ā§ - āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĻ¤ā§ āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻāĻžāĻāĻž, āĻ¯āĻŋāĻ¨āĻŋ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻāĻ°ā§āĻ¨ āĻ¯ā§ āĻ°ā§āĻŦāĻ āĻāĻ ā§āĻ° āĻĒāĻ°āĻŋāĻļā§āĻ°āĻŽ āĻāĻ°ā§, āĻāĻāĻāĻ¨ āĻŦā§āĻ¯āĻā§āĻ¤āĻŋ āĻ¨āĻ¯āĻŧ: āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻā§ āĻ¨āĻŋāĻ°ā§āĻā§āĻˇāĻŖ āĻāĻ°ā§, āĻĄā§āĻ āĻāĻĒāĻĄā§āĻ āĻāĻ°ā§, āĻāĻžāĻāĻā§āĻ˛āĻŋ āĻāĻžāĻ˛ā§ āĻāĻ°ā§āĨ¤
āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻāĻžāĻŦā§, āĻĒā§āĻ°āĻžāĻ¨ā§ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖāĻā§āĻ˛āĻŋāĻ¤ā§, āĻ¤āĻžāĻ° āĻ¸ā§āĻŽā§āĻ¤āĻŋāĻ¤ā§ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻāĻŋāĻ˛ (āĻ¨āĻž, āĻ ā§āĻ¯āĻžāĻŽāĻ¨ā§āĻ¸āĻŋāĻ¯āĻŧāĻž āĻ¨āĻ¯āĻŧ, āĻ¤āĻŦā§ āĻĢāĻžāĻāĻ¸) āĻāĻŦāĻ āĻ˛āĻŋāĻā§āĻ¯āĻžāĻ¸āĻŋ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻāĻžāĻ°āĻāĻŋ āĻāĻŽāĻ¨āĻāĻŋ āĻāĻ¨āĻĢāĻŋāĻāĻžāĻ°ā§ āĻ°āĻ¯āĻŧā§ āĻā§āĻā§
run_duration
- āĻāĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻāĻžāĻ˛ā§ āĻāĻ°āĻžāĻ° āĻŦā§āĻ¯āĻŦāĻ§āĻžāĻ¨āĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨ āĻ¸āĻŦ āĻ āĻŋāĻ āĻāĻā§āĨ¤ - DAG (āĻāĻ°āĻĢā§ "āĻĄā§āĻ¯āĻžāĻ") - "āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļāĻŋāĻ¤ āĻ
ā§āĻ¯āĻžāĻ¸āĻžāĻāĻā§āĻ˛āĻŋāĻ āĻā§āĻ°āĻžāĻĢ", āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻ¸āĻāĻā§āĻāĻž āĻā§āĻŦ āĻāĻŽ āĻ˛ā§āĻāĻā§ āĻŦāĻ˛āĻ¤ā§ āĻĒāĻžāĻ°āĻŦā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ¸āĻ˛ā§ āĻāĻāĻŋ āĻāĻā§ āĻ
āĻĒāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻ¨ā§āĻāĻžāĻ°āĻ
ā§āĻ¯āĻžāĻā§āĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ§āĻžāĻ°āĻ (āĻ¨ā§āĻā§ āĻĻā§āĻā§āĻ¨) āĻŦāĻž SSIS-āĻ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻāĻŦāĻ āĻāĻ¨āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻāĻŋāĻāĻžāĻ¯āĻŧ āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻĢā§āĻ˛ā§-āĻāĻ° āĻāĻāĻāĻŋ āĻ
ā§āĻ¯āĻžāĻ¨āĻžāĻ˛āĻāĨ¤ .
āĻĄā§āĻ¯āĻžāĻāĻā§āĻ˛āĻŋ āĻāĻžāĻĄāĻŧāĻžāĻ, āĻāĻāĻ¨āĻ āĻ¸āĻžāĻŦāĻĄā§āĻ¯āĻžāĻ āĻĨāĻžāĻāĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻ¤āĻŦā§ āĻāĻŽāĻ°āĻž āĻ¸āĻŽā§āĻāĻŦāĻ¤ āĻ¸ā§āĻā§āĻ˛āĻŋ āĻĒāĻžāĻŦ āĻ¨āĻžāĨ¤
- DAG āĻ°āĻžāĻ¨ - āĻĒā§āĻ°āĻžāĻ°āĻŽā§āĻāĻŋāĻ āĻĄā§āĻ, āĻ¯āĻž āĻ¤āĻžāĻ° āĻ¨āĻŋāĻāĻ¸ā§āĻŦ āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧ
execution_date
. āĻāĻāĻ āĻĄā§āĻ¯āĻžāĻā§āĻ° āĻĄā§āĻ¯āĻžāĻāĻ°āĻž āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§ (āĻ¯āĻĻāĻŋ āĻāĻĒāĻ¨āĻŋ āĻ āĻŦāĻļā§āĻ¯āĻ āĻāĻĒāĻ¨āĻžāĻ° āĻāĻžāĻāĻā§āĻ˛āĻŋāĻā§ āĻ āĻĻāĻŽā§āĻ¯ āĻāĻ°ā§ āĻĨāĻžāĻā§āĻ¨)āĨ¤ - āĻ
āĻĒāĻžāĻ°ā§āĻāĻ° āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĻāĻžāĻ¯āĻŧā§ āĻā§āĻĄā§āĻ° āĻā§āĻāĻ°ā§āĨ¤ āĻ¤āĻŋāĻ¨ āĻ§āĻ°āĻ¨ā§āĻ° āĻ
āĻĒāĻžāĻ°ā§āĻāĻ° āĻāĻā§:
- āĻāĻ°ā§āĻŽāĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻŽāĻ¤
PythonOperator
, āĻ¯āĻž āĻ¯ā§āĻā§āĻ¨ā§ (āĻŦā§āĻ§) āĻĒāĻžāĻāĻĨāĻ¨ āĻā§āĻĄ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§; - āĻšāĻ¸ā§āĻ¤āĻžāĻ¨ā§āĻ¤āĻ°, āĻ¯āĻž āĻ¸ā§āĻĨāĻžāĻ¨ āĻĨā§āĻā§ āĻ
āĻ¨ā§āĻ¯ āĻāĻžāĻ¯āĻŧāĻāĻžāĻ¯āĻŧ āĻĄā§āĻāĻž āĻĒāĻ°āĻŋāĻŦāĻšāĻ¨ āĻāĻ°ā§, āĻŦāĻ˛ā§,
MsSqlToHiveTransfer
; - āĻ¸ā§āĻ¨ā§āĻ¸āĻ° āĻ
āĻ¨ā§āĻ¯āĻĻāĻŋāĻā§, āĻāĻāĻŋ āĻāĻĒāĻ¨āĻžāĻā§ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻžāĻ¨āĻžāĻ¤ā§ āĻŦāĻž āĻāĻāĻāĻŋ āĻāĻā§āĻ¨ā§āĻ āĻ¨āĻž āĻšāĻāĻ¯āĻŧāĻž āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻĄā§āĻ¯āĻžāĻāĻāĻŋāĻ° āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨āĻā§ āĻ§ā§āĻ° āĻāĻ°āĻžāĻ° āĻ
āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻŦā§āĨ¤
HttpSensor
āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻ¨ā§āĻĄāĻĒāĻ¯āĻŧā§āĻ¨ā§āĻ āĻāĻžāĻ¨āĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻāĻŦāĻ āĻ¯āĻāĻ¨ āĻāĻžāĻā§āĻā§āĻˇāĻŋāĻ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻā§, āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻļā§āĻ°ā§ āĻāĻ°ā§āĻ¨GoogleCloudStorageToS3Operator
. āĻāĻāĻāĻŋ āĻ āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻŋā§āĻ¸ā§ āĻŽāĻ¨ āĻāĻŋāĻā§āĻāĻžāĻ¸āĻž āĻāĻ°āĻŦā§: "āĻā§āĻ¨? āĻ¸āĻ°ā§āĻŦā§āĻĒāĻ°āĻŋ, āĻāĻĒāĻ¨āĻŋ āĻ āĻŋāĻ āĻ āĻĒāĻžāĻ°ā§āĻāĻ°ā§ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨!" āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ°, āĻ¸ā§āĻĨāĻāĻŋāĻ¤ āĻ āĻĒāĻžāĻ°ā§āĻāĻ°āĻĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻžāĻā§āĻ° āĻĒā§āĻ˛ āĻāĻāĻā§ āĻ¨āĻž āĻĻā§āĻāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯āĨ¤ āĻ¸ā§āĻ¨ā§āĻ¸āĻ° āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧ, āĻā§āĻ āĻāĻ°ā§ āĻāĻŦāĻ āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻĒā§āĻ°āĻā§āĻˇā§āĻāĻžāĻ° āĻāĻā§ āĻŽāĻžāĻ°āĻž āĻ¯āĻžāĻ¯āĻŧāĨ¤
- āĻāĻ°ā§āĻŽāĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻŽāĻ¤
- āĻāĻžāĻ°ā§āĻ¯ - āĻā§āĻˇāĻŋāĻ¤ āĻ āĻĒāĻžāĻ°ā§āĻāĻ°, āĻĒā§āĻ°āĻāĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻŦāĻŋāĻļā§āĻˇā§, āĻāĻŦāĻ āĻĄā§āĻ¯āĻžāĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻāĻ¯ā§āĻā§āĻ¤ āĻāĻ°ā§āĻŽā§āĻ° āĻĒāĻĻā§ āĻāĻ¨ā§āĻ¨ā§āĻ¤ āĻšāĻ¯āĻŧāĨ¤
- āĻāĻžāĻ¸ā§āĻ āĻāĻĻāĻžāĻšāĻ°āĻŖ - āĻ¯āĻāĻ¨ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻĒāĻ°āĻŋāĻāĻ˛ā§āĻĒāĻ¨āĻžāĻāĻžāĻ°ā§ āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛ā§āĻ¨ āĻ¯ā§ āĻĒāĻžāĻ°āĻĢāĻ°ā§āĻŽāĻžāĻ°-āĻāĻ°ā§āĻŽā§āĻĻā§āĻ° āĻ¯ā§āĻĻā§āĻ§ā§ āĻāĻžāĻ āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ¸ā§āĻā§ (āĻ āĻŋāĻ āĻāĻžāĻ¯āĻŧāĻāĻžāĻ¯āĻŧ, āĻ¯āĻĻāĻŋ āĻāĻŽāĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŋ
LocalExecutor
āĻŦāĻž āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻāĻāĻāĻŋ āĻĻā§āĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻ¨ā§āĻĄCeleryExecutor
), āĻāĻāĻŋ āĻ¤āĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻ¸āĻā§āĻ āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻāĻ°ā§ (āĻ āĻ°ā§āĻĨāĻžā§, āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ā§āĻ° āĻāĻāĻāĻŋ āĻ¸ā§āĻ - āĻāĻā§āĻ¸āĻŋāĻāĻŋāĻāĻļāĻ¨ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻāĻžāĻ°), āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻŦāĻž āĻā§āĻ¯ā§āĻ¯āĻŧāĻžāĻ°ā§ āĻā§āĻŽāĻĒā§āĻ˛ā§āĻ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŋāĻ¤ āĻāĻ°ā§ āĻāĻŦāĻ āĻ¤āĻžāĻĻā§āĻ° āĻĒā§āĻ˛ āĻāĻ°ā§āĨ¤
āĻāĻŽāĻ°āĻž āĻāĻžāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋ
āĻĒā§āĻ°āĻĨāĻŽā§, āĻāĻ¸ā§āĻ¨ āĻāĻŽāĻžāĻĻā§āĻ° āĻĄāĻā§āĻ° āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¸ā§āĻāĻŋāĻŽāĻāĻŋāĻ° āĻ°ā§āĻĒāĻ°ā§āĻāĻž āĻĻāĻŋāĻ, āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ°ā§ āĻāĻŽāĻ°āĻž āĻāĻ°āĻ āĻŦā§āĻļāĻŋ āĻāĻ°ā§ āĻŦāĻŋāĻļāĻĻāĻāĻŋāĻ¤ā§ āĻĄā§āĻŦ āĻĻā§āĻŦ, āĻāĻžāĻ°āĻŖ āĻāĻŽāĻ°āĻž āĻāĻŋāĻā§ āĻ -āĻ¤ā§āĻā§āĻ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°āĻŋāĨ¤
āĻ¸ā§āĻ¤āĻ°āĻžāĻ, āĻāĻ° āĻ¸āĻšāĻāĻ¤āĻŽ āĻāĻāĻžāĻ°ā§, āĻāĻ āĻāĻžāĻ¤ā§āĻ¯āĻŧ āĻĄā§āĻ¯āĻžāĻ āĻāĻ° āĻŽāĻ¤ā§ āĻĻā§āĻāĻžāĻŦā§:
from datetime import timedelta, datetime
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from commons.datasources import sql_server_ds
dag = DAG('orders',
schedule_interval=timedelta(hours=6),
start_date=datetime(2020, 7, 8, 0))
def workflow(**context):
print(context)
for conn_id, schema in sql_server_ds:
PythonOperator(
task_id=schema,
python_callable=workflow,
provide_context=True,
dag=dag)
āĻāĻ¸ā§āĻ¨ āĻāĻāĻŋ āĻŦā§āĻ° āĻāĻ°āĻž āĻ¯āĻžāĻ:
- āĻĒā§āĻ°āĻĨāĻŽāĻ¤, āĻāĻŽāĻ°āĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ libs āĻāĻŦāĻ āĻāĻŽāĻĻāĻžāĻ¨āĻŋ āĻāĻ°āĻŋ āĻ āĻ¨ā§āĻ¯āĻāĻŋāĻā§;
sql_server_ds
- āĻāĻāĻžList[namedtuple[str, str]]
āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻžāĻ¨ā§āĻāĻļāĻ¨ āĻĨā§āĻā§ āĻ¸āĻāĻ¯ā§āĻā§āĻ° āĻ¨āĻžāĻŽ āĻāĻŦāĻ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻ¯āĻž āĻĨā§āĻā§ āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ˛ā§āĻ āĻ¨ā§āĻŦ;dag
- āĻāĻŽāĻžāĻĻā§āĻ° āĻĄā§āĻ āĻā§āĻˇāĻŖāĻž, āĻ¯āĻž āĻ āĻāĻ¤ā§āĻ¯āĻž āĻŽāĻ§ā§āĻ¯ā§ āĻšāĻ¤ā§ āĻšāĻŦā§globals()
, āĻ āĻ¨ā§āĻ¯āĻĨāĻžāĻ¯āĻŧ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻāĻŋ āĻā§āĻāĻā§ āĻĒāĻžāĻŦā§ āĻ¨āĻžāĨ¤ āĻĄāĻāĻā§āĻ āĻŦāĻ˛āĻ¤ā§ āĻšāĻŦā§:- āĻ¤āĻžāĻ° āĻ¨āĻžāĻŽ āĻāĻŋ
orders
- āĻāĻ āĻ¨āĻžāĻŽāĻāĻŋ āĻ¤āĻāĻ¨ āĻāĻ¯āĻŧā§āĻŦ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ā§ āĻĒā§āĻ°āĻĻāĻ°ā§āĻļāĻŋāĻ¤ āĻšāĻŦā§, - āĻ¯ā§ āĻ¤āĻŋāĻ¨āĻŋ āĻāĻāĻ āĻā§āĻ˛āĻžāĻ āĻŽāĻ§ā§āĻ¯āĻ°āĻžāĻ¤ āĻĨā§āĻā§ āĻāĻžāĻ āĻāĻ°āĻŦā§āĻ¨,
- āĻāĻŦāĻ āĻāĻāĻŋ āĻāĻžāĻ˛āĻžāĻ¨ā§ āĻāĻāĻŋāĻ¤, āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻĒā§āĻ°āĻ¤āĻŋ 6 āĻāĻ¨ā§āĻāĻž (āĻāĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§ āĻāĻāĻžāĻ¨ā§ āĻāĻ āĻŋāĻ¨ āĻ˛ā§āĻāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯
timedelta()
āĻā§āĻ°āĻšāĻŖāĻ¯ā§āĻā§āĻ¯cron
-āĻ˛āĻžāĻāĻ¨0 0 0/6 ? * * *
, āĻāĻŽ āĻ āĻžāĻ¨ā§āĻĄāĻž āĻāĻ¨ā§āĻ¯ - āĻŽāĻ¤ āĻāĻāĻāĻŋ āĻ āĻāĻŋāĻŦā§āĻ¯āĻā§āĻ¤āĻŋ@daily
);
- āĻ¤āĻžāĻ° āĻ¨āĻžāĻŽ āĻāĻŋ
workflow()
āĻŽā§āĻ˛ āĻāĻžāĻ āĻāĻ°āĻŦā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨ āĻ¨āĻ¯āĻŧāĨ¤ āĻāĻĒāĻžāĻ¤āĻ¤, āĻāĻŽāĻ°āĻž āĻļā§āĻ§ā§ āĻ˛āĻā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻ¸āĻā§āĻ āĻĄāĻžāĻŽā§āĻĒ āĻāĻ°āĻŦāĨ¤- āĻāĻŦāĻ āĻāĻāĻ¨ āĻāĻžāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻ¸āĻšāĻ āĻ¯āĻžāĻĻā§:
- āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¤ā§āĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻžāĻ˛āĻžāĻ¨;
- āĻāĻ°āĻŽā§āĻ āĻāĻ°āĻž
PythonOperator
, āĻ¯āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻĄāĻžāĻŽāĻŋ āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻāĻ°āĻŦā§workflow()
. āĻāĻžāĻ¸ā§āĻā§āĻ° āĻāĻāĻāĻŋ āĻ āĻ¨āĻ¨ā§āĻ¯ (āĻĄā§āĻā§āĻ° āĻŽāĻ§ā§āĻ¯ā§) āĻ¨āĻžāĻŽ āĻāĻ˛ā§āĻ˛ā§āĻ āĻāĻ°āĻ¤ā§ āĻā§āĻ˛āĻŦā§āĻ¨ āĻ¨āĻž āĻāĻŦāĻ āĻĄā§āĻ¯āĻžāĻāĻāĻŋ āĻ¨āĻŋāĻā§āĻ āĻŦā§āĻāĻ§ā§ āĻĻāĻŋāĻ¨āĨ¤ āĻĒāĻ¤āĻžāĻāĻžprovide_context
āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§, āĻĢāĻžāĻāĻļāĻ¨ā§ āĻ āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤ āĻāĻ°ā§āĻā§āĻŽā§āĻ¨ā§āĻ āĻĸāĻžāĻ˛āĻž āĻšāĻŦā§, āĻ¯āĻž āĻāĻŽāĻ°āĻž āĻ¸āĻžāĻŦāĻ§āĻžāĻ¨ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¸āĻāĻā§āĻ°āĻš āĻāĻ°āĻŦ**context
.
āĻāĻĒāĻžāĻ¤āĻ¤ āĻāĻāĻā§āĻā§āĻāĨ¤ āĻāĻŽāĻ°āĻž āĻ¯āĻž āĻĒā§āĻ¯āĻŧā§āĻāĻŋ:
- āĻāĻ¯āĻŧā§āĻŦ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ā§ āĻ¨āĻ¤ā§āĻ¨ āĻĄā§āĻ,
- āĻĻā§āĻĄāĻŧ āĻļāĻ¤āĻžāĻ§āĻŋāĻ āĻāĻžāĻ āĻ¯āĻž āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛āĻāĻžāĻŦā§ āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻāĻ°āĻž āĻšāĻŦā§ (āĻ¯āĻĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§, āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻ¸ā§āĻāĻŋāĻāĻ¸ āĻāĻŦāĻ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§āĻ° āĻā§āĻˇāĻŽāĻ¤āĻž āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻ¯āĻŧ)āĨ¤
āĻāĻ¯āĻŧā§āĻ˛, āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻĒā§āĻ¯āĻŧā§āĻāĻŋāĻ˛āĻžāĻŽ.
āĻā§ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¤āĻž āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻŦā§?
āĻāĻ āĻĒā§āĻ°ā§ āĻāĻŋāĻ¨āĻŋāĻ¸āĻāĻŋ āĻ¸āĻšāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻŽāĻŋ āĻ¸ā§āĻā§āĻ°ā§ āĻāĻ°ā§āĻāĻŋ docker-compose.yml
āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ requirements.txt
āĻ¸āĻŦ āĻ¨ā§āĻĄā§āĻ° āĻāĻĒāĻ°āĨ¤
āĻāĻāĻ¨ āĻāĻāĻŋ āĻāĻ˛ā§ āĻā§āĻā§:
āĻ§ā§āĻ¸āĻ° āĻ¸ā§āĻā§āĻ¯āĻŧāĻžāĻ°āĻā§āĻ˛āĻŋ āĻšāĻ˛ āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻā§ āĻĻā§āĻŦāĻžāĻ°āĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ¤ āĻāĻžāĻ¸ā§āĻ āĻĻā§āĻˇā§āĻāĻžāĻ¨ā§āĻ¤āĨ¤
āĻāĻŽāĻ°āĻž āĻāĻāĻā§ āĻ āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻŋ, āĻāĻ°ā§āĻŽā§āĻ°āĻž āĻāĻžāĻāĻā§āĻ˛ā§ āĻŦāĻ¨ā§āĻ§ āĻāĻ°ā§ āĻĻā§āĻ¨:
āĻ¸āĻŦā§āĻāĻ°āĻž āĻ āĻŦāĻļā§āĻ¯āĻ āĻ¤āĻžāĻĻā§āĻ° āĻāĻžāĻ āĻ¸āĻĢāĻ˛āĻāĻžāĻŦā§ āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻāĻ°ā§āĻā§āĨ¤ āĻ˛āĻžāĻ˛ āĻā§āĻŦ āĻ¸āĻĢāĻ˛ āĻšāĻ¯āĻŧ āĻ¨āĻžāĨ¤
āĻ¯āĻžāĻāĻšā§āĻ, āĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°ā§āĻĄā§ āĻā§āĻ¨ āĻĢā§āĻ˛ā§āĻĄāĻžāĻ° āĻ¨ā§āĻ
./dags
, āĻŽā§āĻļāĻŋāĻ¨ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻā§āĻ¨ āĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻāĻā§āĻļāĻ¨ āĻ¨ā§āĻ - āĻ¸āĻŦ āĻĄā§āĻ¯āĻžāĻ āĻļā§āĻ¯āĻŧā§ āĻāĻā§git
āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻŋāĻāĻ˛ā§āĻ¯āĻžāĻŦā§, āĻāĻŦāĻ āĻāĻŋāĻāĻ˛ā§āĻ¯āĻžāĻŦ āĻ¸āĻŋāĻāĻ āĻŽā§āĻļāĻŋāĻ¨ā§ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻšāĻāĻ¯āĻŧāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻĒāĻĄā§āĻāĻā§āĻ˛āĻŋ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻāĻ°ā§master
.
āĻĢā§āĻ˛ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻāĻā§
āĻļā§āĻ°āĻŽāĻŋāĻāĻ°āĻž āĻ¯āĻāĻ¨ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻļāĻžāĻ¨ā§āĻ¤āĻŋāĻā§ āĻŽāĻžāĻ°āĻā§, āĻ¤āĻāĻ¨ āĻāĻ¸ā§āĻ¨ āĻāĻ°ā§āĻāĻāĻŋ āĻšāĻžāĻ¤āĻŋāĻ¯āĻŧāĻžāĻ° āĻŽāĻ¨ā§ āĻ°āĻžāĻāĻŋ āĻ¯āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻŋāĻā§ āĻĻā§āĻāĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§ - āĻĢā§āĻ˛āĻžāĻāĻ¯āĻŧāĻžāĻ°āĨ¤
āĻāĻ°ā§āĻŽā§ āĻ¨ā§āĻĄā§āĻ° āĻ¸āĻāĻā§āĻˇāĻŋāĻĒā§āĻ¤ āĻ¤āĻĨā§āĻ¯ āĻ¸āĻš āĻĒā§āĻ°āĻĨāĻŽ āĻĒā§āĻˇā§āĻ āĻž:
āĻāĻžāĻāĻā§āĻ˛āĻŋ āĻ¸āĻš āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻ¤ā§āĻŦā§āĻ° āĻĒā§āĻˇā§āĻ āĻž āĻ¯āĻž āĻāĻžāĻ āĻāĻ°āĻ¤ā§ āĻāĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛:
āĻāĻŽāĻžāĻĻā§āĻ° āĻŦā§āĻ°ā§āĻāĻžāĻ°ā§āĻ° āĻ¸ā§āĻā§āĻ¯āĻžāĻāĻžāĻ¸ āĻ¸āĻš āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻŦāĻŋāĻ°āĻā§āĻ¤āĻŋāĻāĻ° āĻĒā§āĻˇā§āĻ āĻž:
āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻāĻā§āĻā§āĻŦāĻ˛ āĻĒā§āĻˇā§āĻ āĻžāĻāĻŋ āĻāĻžāĻ¸ā§āĻ āĻ¸ā§āĻā§āĻ¯āĻžāĻāĻžāĻ¸ āĻā§āĻ°āĻžāĻĢ āĻāĻŦāĻ āĻ¤āĻžāĻĻā§āĻ° āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¸āĻš:
āĻāĻŽāĻ°āĻž underloaded āĻ˛ā§āĻĄ
āĻ¸ā§āĻ¤āĻ°āĻžāĻ, āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻžāĻ āĻļā§āĻˇ āĻšāĻ¯āĻŧā§āĻā§, āĻāĻĒāĻ¨āĻŋ āĻāĻšāĻ¤āĻĻā§āĻ° āĻŦāĻšāĻ¨ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤
āĻāĻŦāĻ āĻ¸ā§āĻāĻžāĻ¨ā§ āĻ āĻ¨ā§āĻ āĻāĻšāĻ¤ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ - āĻāĻ āĻŦāĻž āĻ āĻ¨ā§āĻ¯ āĻāĻžāĻ°āĻŖā§āĨ¤ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ¸āĻ āĻŋāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻāĻ āĻā§āĻŦ āĻ¸ā§āĻā§āĻ¯āĻŧāĻžāĻ°āĻā§āĻ˛āĻŋ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻāĻ°ā§ āĻ¯ā§ āĻĄā§āĻāĻž āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤āĻāĻžāĻŦā§ āĻāĻ¸ā§āĻ¨āĻŋāĨ¤
āĻāĻĒāĻ¨āĻžāĻā§ āĻ˛āĻāĻāĻŋ āĻĻā§āĻāĻ¤ā§ āĻšāĻŦā§ āĻāĻŦāĻ āĻĒāĻ¤āĻŋāĻ¤ āĻāĻžāĻ¸ā§āĻ āĻāĻ¨āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻ¸āĻā§āĻ˛āĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻāĻžāĻ˛ā§ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤
āĻ¯ā§āĻā§āĻ¨ā§ āĻ¸ā§āĻā§āĻ¯āĻŧāĻžāĻ°ā§ āĻā§āĻ˛āĻŋāĻ āĻāĻ°ā§, āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻĒāĻ˛āĻŦā§āĻ§ āĻ ā§āĻ¯āĻžāĻāĻļāĻ¨ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻŦ:
āĻāĻĒāĻ¨āĻŋ āĻ¨āĻŋāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻāĻŦāĻ āĻĒāĻ¤āĻŋāĻ¤ āĻĒāĻ°āĻŋāĻˇā§āĻāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨. āĻ āĻ°ā§āĻĨāĻžā§, āĻāĻŽāĻ°āĻž āĻā§āĻ˛ā§ āĻ¯āĻžāĻ āĻ¯ā§ āĻ¸ā§āĻāĻžāĻ¨ā§ āĻāĻŋāĻā§ āĻŦā§āĻ¯āĻ°ā§āĻĨ āĻšāĻ¯āĻŧā§āĻā§ āĻāĻŦāĻ āĻāĻāĻ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻāĻžāĻ¸ā§āĻ āĻļāĻŋāĻĄāĻŋāĻāĻ˛āĻžāĻ°ā§āĻ° āĻāĻžāĻā§ āĻ¯āĻžāĻŦā§āĨ¤
āĻāĻāĻž āĻ¸ā§āĻĒāĻˇā§āĻ āĻ¯ā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ˛āĻžāĻ˛ āĻ¸ā§āĻā§āĻ¯āĻŧāĻžāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻŽāĻžāĻāĻ¸ āĻĻāĻŋāĻ¯āĻŧā§ āĻāĻāĻŋ āĻāĻ°āĻž āĻā§āĻŦ āĻŽāĻžāĻ¨āĻŦāĻŋāĻ āĻ¨āĻ¯āĻŧ - āĻāĻāĻŋ āĻāĻŽāĻ°āĻž āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻĨā§āĻā§ āĻāĻļāĻž āĻāĻ°āĻŋ āĻ¨āĻžāĨ¤ āĻ¸ā§āĻŦāĻžāĻāĻžāĻŦāĻŋāĻāĻāĻžāĻŦā§āĻ, āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻžāĻā§ āĻāĻŖāĻŦāĻŋāĻ§ā§āĻŦāĻāĻ¸ā§ āĻ
āĻ¸ā§āĻ¤ā§āĻ° āĻ°āĻ¯āĻŧā§āĻā§: Browse/Task Instances
āĻāĻ¸ā§āĻ¨ āĻāĻāĻŦāĻžāĻ°ā§ āĻ¸āĻŦāĻāĻŋāĻā§ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻ¨ āĻāĻ°āĻŋ āĻāĻŦāĻ āĻļā§āĻ¨ā§āĻ¯ā§ āĻ°āĻŋāĻ¸ā§āĻ āĻāĻ°āĻŋ, āĻ¸āĻ āĻŋāĻ āĻāĻāĻā§āĻŽāĻāĻŋāĻ¤ā§ āĻā§āĻ˛āĻŋāĻ āĻāĻ°ā§āĻ¨:
āĻĒāĻ°āĻŋāĻˇā§āĻāĻžāĻ° āĻāĻ°āĻžāĻ° āĻĒāĻ°ā§, āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻ¯āĻžāĻā§āĻ¸āĻŋāĻā§āĻ˛āĻŋ āĻāĻāĻ°āĻāĻŽ āĻĻā§āĻāĻžāĻ¯āĻŧ (āĻ¤āĻžāĻ°āĻž āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§ āĻļāĻŋāĻĄāĻŋāĻāĻ˛āĻžāĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¤āĻžāĻĻā§āĻ° āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻā§):
āĻ¸āĻāĻ¯ā§āĻ, āĻšā§āĻ āĻāĻŦāĻ āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛
āĻāĻāĻž āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ DAG āĻĻā§āĻāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ, update_reports.py
:
from collections import namedtuple
from datetime import datetime, timedelta
from textwrap import dedent
from airflow import DAG
from airflow.contrib.operators.vertica_operator import VerticaOperator
from airflow.operators.email_operator import EmailOperator
from airflow.utils.trigger_rule import TriggerRule
from commons.operators import TelegramBotSendMessage
dag = DAG('update_reports',
start_date=datetime(2020, 6, 7, 6),
schedule_interval=timedelta(days=1),
default_args={'retries': 3, 'retry_delay': timedelta(seconds=10)})
Report = namedtuple('Report', 'source target')
reports = [Report(f'{table}_view', table) for table in [
'reports.city_orders',
'reports.client_calls',
'reports.client_rates',
'reports.daily_orders',
'reports.order_duration']]
email = EmailOperator(
task_id='email_success', dag=dag,
to='{{ var.value.all_the_kings_men }}',
subject='DWH Reports updated',
html_content=dedent("""ĐĐžŅĐŋОда Ņ
ĐžŅĐžŅиĐĩ, ĐžŅŅĐĩŅŅ ОйĐŊОвĐģĐĩĐŊŅ"""),
trigger_rule=TriggerRule.ALL_SUCCESS)
tg = TelegramBotSendMessage(
task_id='telegram_fail', dag=dag,
tg_bot_conn_id='tg_main',
chat_id='{{ var.value.failures_chat }}',
message=dedent("""
ĐĐ°ŅĐ°Ņ, ĐŋŅĐžŅŅĐŋĐ°ĐšŅŅ, ĐŧŅ {{ dag.dag_id }} ŅŅĐžĐŊиĐģи
"""),
trigger_rule=TriggerRule.ONE_FAILED)
for source, target in reports:
queries = [f"TRUNCATE TABLE {target}",
f"INSERT INTO {target} SELECT * FROM {source}"]
report_update = VerticaOperator(
task_id=target.replace('reports.', ''),
sql=queries, vertica_conn_id='dwh',
task_concurrency=1, dag=dag)
report_update >> [email, tg]
āĻ¸āĻŦāĻžāĻ āĻāĻŋ āĻāĻāĻ¨ā§ āĻ°āĻŋāĻĒā§āĻ°ā§āĻ āĻāĻĒāĻĄā§āĻ āĻāĻ°ā§āĻā§? āĻāĻāĻŋ āĻāĻŦāĻžāĻ° āĻ¤āĻžāĻ°: āĻ¤āĻĨā§āĻ¯ āĻā§āĻĨāĻž āĻĨā§āĻā§ āĻĒā§āĻ¤ā§ āĻšāĻŦā§ āĻ¤āĻžāĻ° āĻāĻāĻāĻŋ āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻ°āĻ¯āĻŧā§āĻā§; āĻ¯ā§āĻāĻžāĻ¨ā§ āĻ°āĻžāĻāĻž āĻšāĻŦā§ āĻāĻāĻāĻŋ āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻāĻā§; āĻ¯āĻāĻ¨ āĻ¸āĻŦāĻāĻŋāĻā§ āĻāĻā§ āĻŦāĻž āĻā§āĻā§ āĻ¯āĻžāĻ¯āĻŧ āĻ¤āĻāĻ¨ āĻšāĻ°ā§āĻ¨ āĻĻāĻŋāĻ¤ā§ āĻā§āĻ˛āĻŦā§āĻ¨ āĻ¨āĻž (āĻāĻžāĻ˛, āĻāĻāĻŋ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻ¨āĻ¯āĻŧ, āĻ¨āĻž)āĨ¤
āĻāĻ¸ā§āĻ¨ āĻāĻŦāĻžāĻ° āĻĢāĻžāĻāĻ˛ā§āĻ° āĻŽāĻ§ā§āĻ¯ āĻĻāĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻ¨ āĻāĻŦāĻ āĻ¨āĻ¤ā§āĻ¨ āĻ āĻ¸ā§āĻĒāĻˇā§āĻ āĻāĻŋāĻ¨āĻŋāĻ¸āĻā§āĻ˛āĻŋ āĻĻā§āĻā§āĻ¨:
from commons.operators import TelegramBotSendMessage
- āĻā§āĻ¨ā§ āĻāĻŋāĻā§āĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¨āĻŋāĻāĻ¸ā§āĻŦ āĻ āĻĒāĻžāĻ°ā§āĻāĻ° āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻŦāĻžāĻ§āĻž āĻĻā§āĻ¯āĻŧ āĻ¨āĻž, āĻ¯āĻžāĻ° āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻāĻŽāĻ°āĻž āĻāĻ¨āĻŦā§āĻ˛āĻāĻĄ-āĻ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻā§āĻ āĻŽā§āĻĄāĻŧāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§ āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĨ¤ (āĻāĻŽāĻ°āĻž āĻ¨ā§āĻā§ āĻāĻ āĻ āĻĒāĻžāĻ°ā§āĻāĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻ°āĻ āĻāĻĨāĻž āĻŦāĻ˛āĻŦ);default_args={}
- dag āĻ¤āĻžāĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ āĻĒāĻžāĻ°ā§āĻāĻ°āĻā§ āĻāĻāĻ āĻāĻ°ā§āĻā§āĻŽā§āĻ¨ā§āĻ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§;to='{{ var.value.all_the_kings_men }}'
- āĻā§āĻˇā§āĻ¤ā§āĻ°to
āĻāĻŽāĻžāĻĻā§āĻ° āĻšāĻžāĻ°ā§āĻĄāĻā§āĻĄ āĻāĻ°āĻž āĻšāĻŦā§ āĻ¨āĻž, āĻ¤āĻŦā§ āĻāĻŋāĻ¨āĻāĻž āĻāĻŦāĻ āĻāĻŽā§āĻ˛ā§āĻ° āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻ¸āĻš āĻāĻāĻāĻŋ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻ¤āĻŋāĻļā§āĻ˛āĻāĻžāĻŦā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§, āĻ¯āĻž āĻāĻŽāĻŋ āĻ¸āĻžāĻŦāĻ§āĻžāĻ¨ā§ āĻ°ā§āĻā§āĻāĻŋAdmin/Variables
;trigger_rule=TriggerRule.ALL_SUCCESS
- āĻ āĻĒāĻžāĻ°ā§āĻāĻ° āĻļā§āĻ°ā§ āĻāĻ°āĻžāĻ° āĻļāĻ°ā§āĻ¤āĨ¤ āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¤āĻž āĻāĻžāĻ āĻāĻ°āĻ˛ā§āĻ āĻāĻŋāĻ āĻŋāĻāĻŋ āĻŦāĻ¸āĻĻā§āĻ° āĻāĻžāĻā§ āĻ¯āĻžāĻŦā§ āĻ¸āĻžāĻĢāĻ˛ā§āĻ¯ā§āĻ° āĻ¸āĻžāĻĨā§;tg_bot_conn_id='tg_main'
- āĻ¯ā§āĻā§āĻ¤āĻŋconn_id
āĻāĻŽāĻ°āĻž āĻ¯ā§ āĻ¸āĻāĻ¯ā§āĻ āĻāĻāĻĄāĻŋ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋ āĻ¤āĻž āĻā§āĻ°āĻšāĻŖ āĻāĻ°āĻŋAdmin/Connections
;trigger_rule=TriggerRule.ONE_FAILED
- āĻĒāĻ¤āĻŋāĻ¤ āĻāĻžāĻ āĻĨāĻžāĻāĻ˛ā§āĻ āĻā§āĻ˛āĻŋāĻā§āĻ°āĻžāĻŽā§āĻ° āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋ āĻāĻĄāĻŧā§ āĻ¯āĻžāĻŦā§;task_concurrency=1
- āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻāĻžāĻ¸ā§āĻā§āĻ° āĻāĻāĻžāĻ§āĻŋāĻ āĻāĻžāĻ¸ā§āĻ āĻāĻ¨āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻ¸ā§āĻ° āĻāĻāĻ¯ā§āĻā§ āĻ˛āĻā§āĻ āĻ¨āĻŋāĻˇāĻŋāĻĻā§āĻ§ āĻāĻ°āĻŋā§ˇ āĻ¤āĻž āĻ¨āĻž āĻšāĻ˛ā§ āĻāĻŽāĻ°āĻž āĻāĻāĻ¸āĻā§āĻā§ āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻ˛āĻā§āĻ āĻĒāĻžāĻŦVerticaOperator
(āĻāĻāĻāĻŋ āĻā§āĻŦāĻŋāĻ˛ā§āĻ° āĻĻāĻŋāĻā§ āĻ¤āĻžāĻāĻŋāĻ¯āĻŧā§);report_update >> [email, tg]
- āĻ¸āĻŦVerticaOperator
āĻāĻŋāĻ āĻŋ āĻāĻŦāĻ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°ā§āĻ°āĻŖā§ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻšāĻ¨, āĻāĻāĻāĻžāĻŦā§:
āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¯ā§āĻšā§āĻ¤ā§ āĻ¨ā§āĻāĻŋāĻĢāĻžāĻ¯āĻŧāĻžāĻ° āĻ āĻĒāĻžāĻ°ā§āĻāĻ°āĻĻā§āĻ° āĻ˛āĻā§āĻā§āĻ° āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻļāĻ°ā§āĻ¤ āĻ°āĻ¯āĻŧā§āĻā§, āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻāĻāĻāĻŋ āĻāĻžāĻ āĻāĻ°āĻŦā§āĨ¤ āĻā§āĻ°āĻŋ āĻāĻŋāĻāĻ¤ā§, āĻ¸āĻŦāĻāĻŋāĻā§ āĻāĻāĻā§ āĻāĻŽ āĻāĻŋāĻā§āĻ¯ā§āĻ¯āĻŧāĻžāĻ˛ āĻĻā§āĻāĻžāĻ¯āĻŧ:
āĻāĻŽāĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻļāĻŦā§āĻĻ āĻŦāĻ˛āĻŦ āĻŽā§āĻ¯āĻžāĻā§āĻ°ā§ āĻāĻŦāĻ āĻ¤āĻžāĻĻā§āĻ° āĻŦāĻ¨ā§āĻ§ā§āĻ°āĻž - āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛.
āĻŽā§āĻ¯āĻžāĻā§āĻ°ā§ āĻšāĻ˛ āĻāĻŋāĻ¨āĻāĻž āĻĒā§āĻ˛ā§āĻ¸āĻšā§āĻ˛ā§āĻĄāĻžāĻ° āĻ¯āĻž āĻ āĻĒāĻžāĻ°ā§āĻāĻ° āĻāĻ°ā§āĻā§āĻŽā§āĻ¨ā§āĻā§ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻ¤āĻĨā§āĻ¯ āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻ āĻŽāĻ¤:
SELECT
id,
payment_dtm,
payment_type,
client_id
FROM orders.payments
WHERE
payment_dtm::DATE = '{{ ds }}'::DATE
{{ ds }}
āĻĒā§āĻ°āĻ¸āĻā§āĻ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ā§āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§āĻ¤ā§ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŋāĻ¤ āĻšāĻŦā§ execution_date
āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ā§ YYYY-MM-DD
: 2020-07-14
. āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻāĻžāĻ˛ā§ āĻĻāĻŋāĻ āĻšāĻ˛ āĻ¯ā§ āĻĒā§āĻ°āĻ¸āĻā§āĻ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛āĻā§āĻ˛āĻŋ āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻžāĻ¸ā§āĻ āĻāĻ¨āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻ¸ā§ (āĻā§āĻ°āĻŋ āĻāĻŋāĻāĻ¤ā§ āĻāĻāĻāĻŋ āĻŦāĻ°ā§āĻāĻā§āĻˇā§āĻ¤ā§āĻ°) āĻĒā§āĻ°ā§āĻ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻ¯āĻāĻ¨ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻāĻžāĻ˛ā§ āĻāĻ°āĻž āĻšāĻ¯āĻŧ, āĻ¸ā§āĻĨāĻžāĻ¨āĻ§āĻžāĻ°āĻāĻā§āĻ˛āĻŋ āĻāĻāĻ āĻŽāĻžāĻ¨āĻā§āĻ˛āĻŋāĻ¤ā§ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŋāĻ¤ āĻšāĻŦā§āĨ¤
āĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŋāĻ¤ āĻŽāĻžāĻ¨āĻā§āĻ˛āĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻāĻžāĻ¸ā§āĻ āĻāĻ¨āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻ¸ā§ āĻ°ā§āĻ¨ā§āĻĄāĻžāĻ° āĻāĻ°āĻž āĻŦā§āĻ¤āĻžāĻŽ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻĻā§āĻāĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻāĻāĻāĻžāĻŦā§ āĻāĻāĻāĻŋ āĻāĻŋāĻ āĻŋ āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻāĻžāĻ:
āĻāĻŦāĻ āĻ¤āĻžāĻ āĻāĻāĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻāĻžāĻā§:
āĻ¸āĻ°ā§āĻŦāĻļā§āĻˇ āĻāĻĒāĻ˛āĻŦā§āĻ§ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ
āĻ¨ā§āĻ¤āĻ°ā§āĻ¨āĻŋāĻ°ā§āĻŽāĻŋāĻ¤ āĻŽā§āĻ¯āĻžāĻā§āĻ°ā§āĻā§āĻ˛āĻŋāĻ° āĻāĻāĻāĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻāĻāĻžāĻ¨ā§ āĻāĻĒāĻ˛āĻŦā§āĻ§:
āĻ¤āĻžāĻāĻžāĻĄāĻŧāĻž, āĻĒā§āĻ˛āĻžāĻāĻāĻ¨āĻā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§, āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻ¨āĻŋāĻāĻ¸ā§āĻŦ āĻŽā§āĻ¯āĻžāĻā§āĻ°ā§ āĻā§āĻˇāĻŖāĻž āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ, āĻ¤āĻŦā§ āĻāĻāĻŋ āĻ āĻ¨ā§āĻ¯ āĻāĻ˛ā§āĻĒāĨ¤
āĻĒā§āĻ°ā§āĻŦāĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŋāĻ¤ āĻāĻŋāĻ¨āĻŋāĻ¸āĻā§āĻ˛āĻŋ āĻāĻžāĻĄāĻŧāĻžāĻ, āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ā§āĻ° āĻŽāĻžāĻ¨āĻā§āĻ˛āĻŋāĻā§ āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŋ (āĻāĻŽāĻŋ āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§ āĻāĻĒāĻ°ā§āĻ° āĻā§āĻĄā§ āĻāĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋ)āĨ¤ āĻāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻ¯āĻžāĻ Admin/Variables
āĻāĻŋāĻā§ āĻāĻŋāĻ¨āĻŋāĻ¸:
āĻāĻĒāĻ¨āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻ¸āĻŦāĻāĻŋāĻā§:
TelegramBotSendMessage(chat_id='{{ var.value.failures_chat }}')
āĻŽāĻžāĻ¨ āĻāĻāĻāĻŋ āĻ¸ā§āĻā§āĻ˛āĻžāĻ° āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻ āĻĨāĻŦāĻž āĻāĻāĻŋ JSONāĻ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ JSON āĻāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§:
bot_config
{
"bot": {
"token": 881hskdfASDA16641,
"name": "Verter"
},
"service": "TG"
}
āĻļā§āĻ§ā§ āĻĒāĻāĻ¨ā§āĻĻāĻ¸āĻ āĻā§āĻāĻŋāĻ° āĻĒāĻĨāĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻ¨: {{ var.json.bot_config.bot.token }}
.
āĻāĻŽāĻŋ āĻāĻā§āĻˇāĻ°āĻŋāĻ āĻ
āĻ°ā§āĻĨā§ āĻāĻāĻāĻŋ āĻļāĻŦā§āĻĻ āĻŦāĻ˛āĻŦ āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻ¸ā§āĻā§āĻ°āĻŋāĻ¨āĻļāĻ āĻĻā§āĻāĻžāĻŦ āĻ¸āĻāĻ¯ā§āĻ. āĻ¸āĻŦāĻāĻŋāĻā§ āĻāĻāĻžāĻ¨ā§ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ: āĻĒā§āĻˇā§āĻ āĻžāĻ¯āĻŧ Admin/Connections
āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋ, āĻ¸ā§āĻāĻžāĻ¨ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ˛āĻāĻāĻ¨/āĻĒāĻžāĻ¸āĻāĻ¯āĻŧāĻžāĻ°ā§āĻĄ āĻāĻŦāĻ āĻāĻ°āĻ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻāĻžāĻ° āĻ¯ā§āĻ āĻāĻ°āĻŋāĨ¤ āĻāĻāĻžāĻ° āĻŽāĻ¤:
āĻĒāĻžāĻ¸āĻāĻ¯āĻŧāĻžāĻ°ā§āĻĄāĻā§āĻ˛āĻŋ āĻāĻ¨āĻā§āĻ°āĻŋāĻĒā§āĻ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§ (āĻĄāĻŋāĻĢāĻ˛ā§āĻā§āĻ° āĻā§āĻ¯āĻŧā§ āĻāĻ°āĻ āĻĒā§āĻā§āĻāĻžāĻ¨ā§āĻĒā§āĻā§āĻāĻāĻžāĻŦā§), āĻ
āĻĨāĻŦāĻž āĻāĻĒāĻ¨āĻŋ āĻ¸āĻāĻ¯ā§āĻā§āĻ° āĻ§āĻ°āĻ¨āĻāĻŋ āĻā§āĻĄāĻŧā§ āĻĻāĻŋāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ (āĻ¯ā§āĻŽāĻ¨ āĻāĻŽāĻŋ āĻāĻ°ā§āĻāĻŋ tg_main
) - āĻāĻ¸āĻ˛ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻāĻŋ āĻšāĻ˛ āĻ¯ā§ āĻĒā§āĻ°āĻāĻžāĻ°ā§āĻ° āĻ¤āĻžāĻ˛āĻŋāĻāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻŽāĻĄā§āĻ˛āĻā§āĻ˛āĻŋāĻ¤ā§ āĻšāĻžāĻ°ā§āĻĄāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ°āĻ¯ā§āĻā§āĻ¤ āĻāĻŦāĻ āĻ¸ā§āĻ°ā§āĻ¸ āĻā§āĻĄāĻā§āĻ˛āĻŋāĻ¤ā§ āĻ¨āĻž āĻāĻŋāĻ¯āĻŧā§ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŋāĻ¤ āĻāĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ āĻ¨āĻž (āĻ¯āĻĻāĻŋ āĻšāĻ āĻžā§ āĻāĻŽāĻŋ āĻāĻŋāĻā§ āĻā§āĻāĻ˛ āĻ¨āĻž āĻāĻ°āĻŋ āĻ¤āĻŦā§ āĻĻāĻ¯āĻŧāĻž āĻāĻ°ā§ āĻāĻŽāĻžāĻā§ āĻ¸āĻāĻļā§āĻ§āĻ¨ āĻāĻ°ā§āĻ¨), āĻ¤āĻŦā§ āĻāĻŋāĻā§āĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻ°ā§āĻĄāĻŋāĻ āĻĒā§āĻ¤ā§ āĻŦāĻžāĻ§āĻž āĻĻā§āĻŦā§ āĻ¨āĻž āĻ¨āĻžāĻŽ
āĻāĻĒāĻ¨āĻŋ āĻāĻāĻ āĻ¨āĻžāĻŽā§āĻ° āĻ¸āĻžāĻĨā§ āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻāĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨: āĻāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻĒāĻĻā§āĻ§āĻ¤āĻŋ BaseHook.get_connection()
, āĻ¯āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻ¨āĻžāĻŽā§ āĻ¸āĻāĻ¯ā§āĻ āĻĒāĻžāĻ¯āĻŧ, āĻĻā§āĻŦā§ āĻāĻ˛ā§āĻŽā§āĻ˛ā§ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻ¨āĻžāĻŽāĻāĻ°āĻŖ āĻĨā§āĻā§ (āĻ°āĻžāĻāĻ¨ā§āĻĄ āĻ°āĻŦāĻŋāĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻāĻ°āĻ āĻ¯ā§āĻā§āĻ¤āĻŋāĻ āĻšāĻŦā§, āĻ¤āĻŦā§ āĻāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻŦāĻŋāĻāĻžāĻļāĻāĻžāĻ°ā§āĻĻā§āĻ° āĻŦāĻŋāĻŦā§āĻā§āĻ° āĻāĻĒāĻ° āĻā§āĻĄāĻŧā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻ)āĨ¤
āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ āĻāĻŦāĻ āĻ¸āĻāĻ¯ā§āĻāĻā§āĻ˛āĻŋ āĻ āĻŦāĻļā§āĻ¯āĻ āĻĻā§āĻ°ā§āĻĻāĻžāĻ¨ā§āĻ¤ āĻ¸āĻ°āĻā§āĻāĻžāĻŽ, āĻ¤āĻŦā§ āĻāĻžāĻ°āĻ¸āĻžāĻŽā§āĻ¯ āĻ¨āĻž āĻšāĻžāĻ°āĻžāĻ¨ā§ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ: āĻāĻĒāĻ¨āĻžāĻ° āĻĒā§āĻ°āĻŦāĻžāĻšā§āĻ° āĻā§āĻ¨ āĻ āĻāĻļāĻā§āĻ˛āĻŋ āĻāĻĒāĻ¨āĻŋ āĻā§āĻĄā§ āĻ¸āĻā§āĻāĻ¯āĻŧ āĻāĻ°ā§āĻ¨ āĻāĻŦāĻ āĻāĻĒāĻ¨āĻŋ āĻ¸ā§āĻā§āĻ°ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻā§āĻ¨ āĻ āĻāĻļāĻā§āĻ˛āĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĻā§ āĻĻā§āĻ¨ā§ˇ āĻāĻāĻĻāĻŋāĻā§, āĻĻā§āĻ°ā§āĻ¤ āĻŽāĻžāĻ¨ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻž āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻāĻ¨āĻ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻāĻāĻŋ āĻŽā§āĻāĻ˛āĻŋāĻ āĻŦāĻā§āĻ¸, UI āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§āĨ¤ āĻ āĻ¨ā§āĻ¯āĻĻāĻŋāĻā§, āĻāĻāĻŋ āĻāĻāĻ¨āĻ āĻŽāĻžāĻāĻ¸ āĻā§āĻ˛āĻŋāĻā§ āĻĢāĻŋāĻ°ā§ āĻāĻ¸āĻž, āĻ¯āĻž āĻĨā§āĻā§ āĻāĻŽāĻ°āĻž (āĻāĻŽāĻŋ) āĻĒāĻ°āĻŋāĻ¤ā§āĻ°āĻžāĻŖ āĻĒā§āĻ¤ā§ āĻā§āĻ¯āĻŧā§āĻāĻŋāĻ˛āĻžāĻŽāĨ¤
āĻ¸āĻāĻ¯ā§āĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻžāĻ āĻāĻ°āĻž āĻāĻžāĻāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻšā§āĻ. āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻāĻžāĻŦā§, āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻšā§āĻāĻā§āĻ˛āĻŋ āĻāĻāĻŋāĻā§ āĻ¤ā§āĻ¤ā§āĻ¯āĻŧ āĻĒāĻā§āĻˇā§āĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻž āĻāĻŦāĻ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻāĻ¯ā§āĻā§āĻ¤ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻāĨ¤ āĻ¯ā§āĻŽāĻ¨, JiraHook
āĻāĻŋāĻ°āĻžāĻ° āĻ¸āĻžāĻĨā§ āĻ¯ā§āĻāĻžāĻ¯ā§āĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻ āĻā§āĻ˛āĻŦā§ (āĻāĻĒāĻ¨āĻŋ āĻāĻžāĻāĻā§āĻ˛āĻŋ āĻ¸āĻžāĻŽāĻ¨ā§ āĻāĻŦāĻ āĻĒāĻŋāĻāĻ¨ā§ āĻ¸āĻ°āĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨), āĻāĻŦāĻ āĻāĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§ SambaHook
āĻāĻĒāĻ¨āĻŋ āĻāĻāĻāĻŋ āĻ¸ā§āĻĨāĻžāĻ¨ā§āĻ¯āĻŧ āĻĢāĻžāĻāĻ˛ āĻ§āĻžāĻā§āĻāĻž āĻĻāĻŋāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ smb
-āĻŦāĻŋāĻ¨ā§āĻĻā§āĨ¤
āĻāĻžāĻ¸ā§āĻāĻŽ āĻ āĻĒāĻžāĻ°ā§āĻāĻ° āĻĒāĻžāĻ°ā§āĻ¸āĻŋāĻ
āĻāĻŦāĻ āĻāĻŽāĻ°āĻž āĻāĻāĻŋ āĻāĻŋāĻāĻžāĻŦā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻ¤āĻž āĻĻā§āĻāĻ¤ā§ āĻāĻžāĻāĻžāĻāĻžāĻāĻŋ āĻĒā§āĻ¯āĻŧā§āĻāĻŋāĻ˛āĻžāĻŽ TelegramBotSendMessage
āĻā§āĻĄ commons/operators.py
āĻĒā§āĻ°āĻā§āĻ¤ āĻ
āĻĒāĻžāĻ°ā§āĻāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§:
from typing import Union
from airflow.operators import BaseOperator
from commons.hooks import TelegramBotHook, TelegramBot
class TelegramBotSendMessage(BaseOperator):
"""Send message to chat_id using TelegramBotHook
Example:
>>> TelegramBotSendMessage(
... task_id='telegram_fail', dag=dag,
... tg_bot_conn_id='tg_bot_default',
... chat_id='{{ var.value.all_the_young_dudes_chat }}',
... message='{{ dag.dag_id }} failed :(',
... trigger_rule=TriggerRule.ONE_FAILED)
"""
template_fields = ['chat_id', 'message']
def __init__(self,
chat_id: Union[int, str],
message: str,
tg_bot_conn_id: str = 'tg_bot_default',
*args, **kwargs):
super().__init__(*args, **kwargs)
self._hook = TelegramBotHook(tg_bot_conn_id)
self.client: TelegramBot = self._hook.client
self.chat_id = chat_id
self.message = message
def execute(self, context):
print(f'Send "{self.message}" to the chat {self.chat_id}')
self.client.send_message(chat_id=self.chat_id,
message=self.message)
āĻāĻāĻžāĻ¨ā§, āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĻ¤ā§ āĻ āĻ¨ā§āĻ¯ āĻ¸āĻŦāĻāĻŋāĻā§āĻ° āĻŽāĻ¤ā§, āĻ¸āĻŦāĻāĻŋāĻā§ āĻā§āĻŦ āĻ¸āĻšāĻ:
- āĻĨā§āĻā§ āĻāĻ¤ā§āĻ¤āĻ°āĻžāĻ§āĻŋāĻāĻžāĻ°āĻ¸ā§āĻ¤ā§āĻ°ā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤
BaseOperator
, āĻ¯āĻž āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§-āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻŋāĻ¨āĻŋāĻ¸ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°ā§ (āĻāĻĒāĻ¨āĻžāĻ° āĻ āĻŦāĻ¸āĻ°ā§āĻ° āĻĻāĻŋāĻā§ āĻ¤āĻžāĻāĻžāĻ¨) - āĻā§āĻˇāĻŋāĻ¤ āĻā§āĻˇā§āĻ¤ā§āĻ°
template_fields
, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻāĻŋāĻ¨āĻāĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻŽā§āĻ¯āĻžāĻā§āĻ°ā§āĻā§āĻ˛āĻŋ āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻāĻ°āĻŦā§ā§ˇ - āĻāĻ¨ā§āĻ¯ āĻ¸āĻ āĻŋāĻ āĻ¯ā§āĻā§āĻ¤āĻŋ āĻ¸āĻžāĻāĻŋāĻ¯āĻŧā§āĻā§āĻ¨
__init__()
, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻ¸ā§āĻāĻžāĻ¨ā§ āĻĄāĻŋāĻĢāĻ˛ā§āĻ āĻ¸ā§āĻ āĻāĻ°ā§āĻ¨āĨ¤ - āĻāĻŽāĻ°āĻž āĻĒā§āĻ°ā§āĻŦāĻĒā§āĻ°ā§āĻˇā§āĻ° āĻ¸ā§āĻāĻ¨āĻž āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§āĻ āĻā§āĻ˛ā§ āĻ¯āĻžāĻāĻ¨āĻŋāĨ¤
- āĻ¸āĻāĻļā§āĻ˛āĻŋāĻˇā§āĻ āĻšā§āĻ āĻā§āĻ˛āĻ˛ā§āĻ¨
TelegramBotHook
āĻāĻāĻŋ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻ āĻ āĻŦāĻā§āĻā§āĻ āĻĒā§āĻ¯āĻŧā§āĻāĻŋāĨ¤ - āĻāĻāĻžāĻ°āĻ°āĻžāĻāĻĄ (āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻ¸āĻāĻā§āĻāĻžāĻ¯āĻŧāĻŋāĻ¤) āĻĒāĻĻā§āĻ§āĻ¤āĻŋ
BaseOperator.execute()
, āĻ āĻĒāĻžāĻ°ā§āĻāĻ° āĻāĻžāĻ˛ā§ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ˛ā§ āĻ¯ā§ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§ āĻā§āĻāĻ āĻāĻ°āĻŦā§ - āĻāĻ¤ā§ āĻāĻŽāĻ°āĻž āĻ˛āĻ āĻāĻ¨ āĻāĻ°āĻ¤ā§ āĻā§āĻ˛ā§ āĻāĻŋāĻ¯āĻŧā§ āĻŽā§āĻ˛ āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻŋ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻŦāĨ¤ (āĻāĻŽāĻ°āĻž āĻ˛āĻ āĻāĻ¨ āĻāĻ°āĻŋ, āĻ¯āĻžāĻāĻšā§āĻ, āĻĄāĻžāĻ¨ āĻāĻ¨stdout
иstderr
- āĻŦāĻžāĻ¯āĻŧā§āĻĒā§āĻ°āĻŦāĻžāĻš āĻ¸āĻŦāĻāĻŋāĻā§āĻā§ āĻāĻāĻāĻžāĻŦā§, āĻ¸ā§āĻ¨ā§āĻĻāĻ°āĻāĻžāĻŦā§ āĻŽā§āĻĄāĻŧāĻžāĻ¨ā§ āĻšāĻŦā§, āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§ āĻāĻāĻŋ āĻĒāĻāĻŋāĻ¯āĻŧā§ āĻĢā§āĻ˛āĻŦā§āĨ¤)
āĻĻā§āĻāĻž āĻ¯āĻžāĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻŋ āĻāĻā§ commons/hooks.py
. āĻĢāĻžāĻāĻ˛ā§āĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻ
āĻāĻļ, āĻšā§āĻ āĻ¨āĻŋāĻā§āĻ:
from typing import Union
from airflow.hooks.base_hook import BaseHook
from requests_toolbelt.sessions import BaseUrlSession
class TelegramBotHook(BaseHook):
"""Telegram Bot API hook
Note: add a connection with empty Conn Type and don't forget
to fill Extra:
{"bot_token": "YOuRAwEsomeBOtToKen"}
"""
def __init__(self,
tg_bot_conn_id='tg_bot_default'):
super().__init__(tg_bot_conn_id)
self.tg_bot_conn_id = tg_bot_conn_id
self.tg_bot_token = None
self.client = None
self.get_conn()
def get_conn(self):
extra = self.get_connection(self.tg_bot_conn_id).extra_dejson
self.tg_bot_token = extra['bot_token']
self.client = TelegramBot(self.tg_bot_token)
return self.client
āĻāĻŽāĻŋ āĻāĻāĻžāĻ¨ā§ āĻā§ āĻŦā§āĻ¯āĻžāĻā§āĻ¯āĻž āĻāĻ°āĻŦ āĻ¤āĻžāĻ āĻāĻžāĻ¨āĻŋ āĻ¨āĻž, āĻāĻŽāĻŋ āĻļā§āĻ§ā§ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻāĻā§āĻ˛āĻŋ āĻ¨ā§āĻ āĻāĻ°āĻŦ:
- āĻāĻŽāĻ°āĻž āĻāĻ¤ā§āĻ¤āĻ°āĻžāĻ§āĻŋāĻāĻžāĻ°āĻ¸ā§āĻ¤ā§āĻ°ā§ āĻĒāĻžāĻ, āĻ¯ā§āĻā§āĻ¤āĻŋāĻā§āĻ˛āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻŋāĻ¨ā§āĻ¤āĻž āĻāĻ°āĻŋ - āĻŦā§āĻļāĻŋāĻ°āĻāĻžāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ āĻāĻāĻŋ āĻāĻ āĻšāĻŦā§:
conn_id
; - āĻāĻāĻžāĻ°āĻ°āĻžāĻāĻĄāĻŋāĻ āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ: āĻāĻŽāĻŋ āĻ¨āĻŋāĻā§āĻā§ āĻ¸ā§āĻŽāĻŋāĻ¤ āĻāĻ°ā§āĻāĻŋ
get_conn()
, āĻ¯āĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻŽāĻŋ āĻ¨āĻžāĻŽ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ¸āĻāĻ¯ā§āĻā§āĻ° āĻĒāĻ°āĻžāĻŽāĻŋāĻ¤āĻŋāĻā§āĻ˛āĻŋ āĻĒāĻžāĻ āĻāĻŦāĻ āĻā§āĻŦāĻ˛ āĻŦāĻŋāĻāĻžāĻāĻāĻŋ āĻĒāĻžāĻextra
(āĻāĻāĻŋ āĻāĻāĻāĻŋ JSON āĻā§āĻˇā§āĻ¤ā§āĻ°), āĻ¯ā§āĻāĻžāĻ¨ā§ āĻāĻŽāĻŋ (āĻāĻŽāĻžāĻ° āĻ¨āĻŋāĻā§āĻ° āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻ āĻ¨ā§āĻ¸āĻžāĻ°ā§!) āĻā§āĻ˛āĻŋāĻā§āĻ°āĻžāĻŽ āĻŦāĻ āĻā§āĻā§āĻ¨ āĻ°ā§āĻā§āĻāĻŋ:{"bot_token": "YOuRAwEsomeBOtToKen"}
. - āĻāĻŽāĻŋ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻ¤ā§āĻ°āĻŋ
TelegramBot
, āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻā§āĻā§āĻ¨ āĻĒā§āĻ°āĻĻāĻžāĻ¨.
āĻāĻāĻžāĻ¨ā§āĻ āĻļā§āĻˇ. āĻāĻĒāĻ¨āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻāĻāĻŋ āĻšā§āĻ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻ āĻĒā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ TelegramBotHook().clent
āĻŦāĻž TelegramBotHook().get_conn()
.
āĻāĻŦāĻ āĻĢāĻžāĻāĻ˛ā§āĻ° āĻĻā§āĻŦāĻŋāĻ¤ā§āĻ¯āĻŧ āĻ
āĻāĻļ, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻāĻŽāĻŋ āĻā§āĻ˛āĻŋāĻā§āĻ°āĻžāĻŽ REST API-āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻŽāĻžāĻāĻā§āĻ°ā§āĻāĻ°ā§āĻ¯āĻžāĻĒāĻžāĻ° āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋ, āĻ¯āĻžāĻ¤ā§ āĻāĻāĻ āĻā§āĻ¨ā§ āĻ¨āĻž āĻāĻ¨ā§ python-telegram-bot
sendMessage
.
class TelegramBot:
"""Telegram Bot API wrapper
Examples:
>>> TelegramBot('YOuRAwEsomeBOtToKen', '@myprettydebugchat').send_message('Hi, darling')
>>> TelegramBot('YOuRAwEsomeBOtToKen').send_message('Hi, darling', chat_id=-1762374628374)
"""
API_ENDPOINT = 'https://api.telegram.org/bot{}/'
def __init__(self, tg_bot_token: str, chat_id: Union[int, str] = None):
self._base_url = TelegramBot.API_ENDPOINT.format(tg_bot_token)
self.session = BaseUrlSession(self._base_url)
self.chat_id = chat_id
def send_message(self, message: str, chat_id: Union[int, str] = None):
method = 'sendMessage'
payload = {'chat_id': chat_id or self.chat_id,
'text': message,
'parse_mode': 'MarkdownV2'}
response = self.session.post(method, data=payload).json()
if not response.get('ok'):
raise TelegramBotException(response)
class TelegramBotException(Exception):
def __init__(self, *args, **kwargs):
super().__init__((args, kwargs))
āĻ¸āĻ āĻŋāĻ āĻāĻĒāĻžāĻ¯āĻŧ āĻšāĻ˛ āĻāĻāĻŋ āĻ¸āĻŦ āĻ¯ā§āĻ āĻāĻ°āĻž:
TelegramBotSendMessage
,TelegramBotHook
,TelegramBot
- āĻĒā§āĻ˛āĻžāĻāĻāĻ¨ā§, āĻāĻāĻāĻŋ āĻĒāĻžāĻŦāĻ˛āĻŋāĻ āĻ°āĻŋāĻĒā§āĻāĻŋāĻāĻ°āĻŋ āĻ°āĻžāĻā§āĻ¨ āĻāĻŦāĻ āĻāĻĒā§āĻ¨ āĻ¸ā§āĻ°ā§āĻ¸ā§ āĻĻāĻŋāĻ¨āĨ¤
āĻ¯āĻāĻ¨ āĻāĻŽāĻ°āĻž āĻāĻ āĻ¸āĻŦ āĻ āĻ§ā§āĻ¯āĻ¯āĻŧāĻ¨ āĻāĻ°āĻāĻŋāĻ˛āĻžāĻŽ, āĻāĻŽāĻžāĻĻā§āĻ° āĻ°āĻŋāĻĒā§āĻ°ā§āĻ āĻāĻĒāĻĄā§āĻ āĻ¸āĻĢāĻ˛āĻāĻžāĻŦā§ āĻŦā§āĻ¯āĻ°ā§āĻĨ āĻšāĻ¯āĻŧā§āĻā§ āĻāĻŦāĻ āĻāĻŽāĻžāĻā§ āĻā§āĻ¯āĻžāĻ¨ā§āĻ˛ā§ āĻāĻāĻāĻŋ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¤ā§ āĻ¸āĻā§āĻˇāĻŽ āĻšāĻ¯āĻŧā§āĻā§ā§ˇ āĻāĻŽāĻŋ āĻāĻāĻž āĻā§āĻ˛ āĻāĻŋāĻ¨āĻž āĻĻā§āĻāĻ¤ā§ āĻā§āĻ āĻāĻ°āĻ¤ā§ āĻ¯āĻžāĻā§āĻāĻŋ...
āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻā§āĻ°ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻŋāĻā§ āĻā§āĻā§ āĻā§āĻā§! āĻāĻāĻžāĻ āĻāĻŋ āĻāĻŽāĻ°āĻž āĻāĻļāĻž āĻāĻ°āĻāĻŋāĻ˛āĻžāĻŽ āĻ¨āĻž? āĻšā§āĻŦāĻšā§ !
āĻāĻĒāĻ¨āĻŋ āĻĸāĻžāĻ˛āĻž āĻ¯āĻžāĻā§āĻā§āĻ¨?
āĻ¤ā§āĻŽāĻžāĻ° āĻāĻŋ āĻŽāĻ¨ā§ āĻšāĻ¯āĻŧ āĻāĻŽāĻŋ āĻāĻŋāĻā§ āĻŽāĻŋāĻ¸ āĻāĻ°ā§āĻāĻŋ? āĻŽāĻ¨ā§ āĻšāĻā§āĻā§ āĻ¤āĻŋāĻ¨āĻŋ āĻāĻ¸āĻāĻŋāĻāĻāĻ˛ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻĨā§āĻā§ āĻāĻžāĻ°ā§āĻāĻŋāĻāĻžāĻ¯āĻŧ āĻĄā§āĻāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻļā§āĻ°ā§āĻ¤āĻŋ āĻĻāĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛ā§āĻ¨, āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ°ā§ āĻ¤āĻŋāĻ¨āĻŋ āĻ¤āĻž āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛ā§āĻ¨ āĻāĻŦāĻ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻāĻŋ āĻĨā§āĻā§ āĻ¸āĻ°ā§ āĻāĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛ā§āĻ¨, āĻŦāĻāĻžāĻā§!
āĻāĻ āĻ¨ā§āĻļāĻāĻ¸āĻ¤āĻž āĻāĻā§āĻāĻžāĻā§āĻ¤ āĻāĻŋāĻ˛, āĻāĻŽāĻžāĻā§ āĻā§āĻŦāĻ˛ āĻāĻĒāĻ¨āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŋāĻā§ āĻĒāĻ°āĻŋāĻāĻžāĻˇāĻž āĻŦā§āĻāĻžāĻ¤ā§ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛āĨ¤ āĻāĻāĻ¨ āĻāĻĒāĻ¨āĻŋ āĻāĻ°āĻ āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤
āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻ°āĻŋāĻāĻ˛ā§āĻĒāĻ¨āĻž āĻāĻŋāĻ˛ āĻāĻ:
- āĻĻāĻžāĻ āĻāĻ°
- āĻāĻžāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§āĻ¨
- āĻĻā§āĻā§āĻ¨ āĻ¸āĻŦāĻāĻŋāĻā§ āĻāĻ¤ āĻ¸ā§āĻ¨ā§āĻĻāĻ°
- āĻĒā§āĻ°āĻŖ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻļāĻ¨ āĻ¨āĻŽā§āĻŦāĻ° āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻāĻ°ā§āĻ¨
- SQL āĻ¸āĻžāĻ°ā§āĻāĻžāĻ° āĻĨā§āĻā§ āĻĄā§āĻāĻž āĻĒāĻžāĻ¨
- āĻāĻžāĻ°ā§āĻāĻŋāĻāĻžāĻ¯āĻŧ āĻĄā§āĻāĻž āĻ°āĻžāĻā§āĻ¨
- āĻĒāĻ°āĻŋāĻ¸āĻāĻā§āĻ¯āĻžāĻ¨ āĻ¸āĻāĻā§āĻ°āĻš āĻāĻ°ā§āĻ¨
āĻ¸ā§āĻ¤āĻ°āĻžāĻ, āĻāĻ āĻ¸āĻŦ āĻĒā§āĻ¤ā§ āĻāĻŦāĻ āĻāĻ˛āĻŽāĻžāĻ¨, āĻāĻŽāĻŋ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻā§āĻ āĻ¸āĻāĻ¯ā§āĻāĻ¨ āĻāĻ°āĻž docker-compose.yml
:
docker-compose.db.yml
version: '3.4'
x-mssql-base: &mssql-base
image: mcr.microsoft.com/mssql/server:2017-CU21-ubuntu-16.04
restart: always
environment:
ACCEPT_EULA: Y
MSSQL_PID: Express
SA_PASSWORD: SayThanksToSatiaAt2020
MSSQL_MEMORY_LIMIT_MB: 1024
services:
dwh:
image: jbfavre/vertica:9.2.0-7_ubuntu-16.04
mssql_0:
<<: *mssql-base
mssql_1:
<<: *mssql-base
mssql_2:
<<: *mssql-base
mssql_init:
image: mio101/py3-sql-db-client-base
command: python3 ./mssql_init.py
depends_on:
- mssql_0
- mssql_1
- mssql_2
environment:
SA_PASSWORD: SayThanksToSatiaAt2020
volumes:
- ./mssql_init.py:/mssql_init.py
- ./dags/commons/datasources.py:/commons/datasources.py
āĻ¸ā§āĻāĻžāĻ¨ā§ āĻāĻŽāĻ°āĻž āĻāĻ¤ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻŋ:
- āĻšā§āĻ¸ā§āĻ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻžāĻ°ā§āĻāĻŋāĻāĻž
dwh
āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻĄāĻŋāĻĢāĻ˛ā§āĻ āĻ¸ā§āĻāĻŋāĻāĻ¸ āĻ¸āĻš, - SQL āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§āĻ° āĻ¤āĻŋāĻ¨āĻāĻŋ āĻāĻĻāĻžāĻšāĻ°āĻŖ,
- āĻāĻŽāĻ°āĻž āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§āĻ¤ā§ āĻāĻŋāĻā§ āĻĄā§āĻāĻž āĻĻāĻŋāĻ¯āĻŧā§ āĻĄā§āĻāĻžāĻŦā§āĻ¸āĻā§āĻ˛āĻŋ āĻĒā§āĻ°āĻŖ āĻāĻ°āĻŋ (āĻā§āĻ¨ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ āĻ¤āĻž āĻĻā§āĻāĻŦā§āĻ¨ āĻ¨āĻž
mssql_init.py
!)
āĻāĻŽāĻ°āĻž āĻāĻ¤āĻŦāĻžāĻ°ā§āĻ° āĻā§āĻ¯āĻŧā§ āĻāĻŋāĻā§āĻāĻž āĻāĻāĻŋāĻ˛ āĻāĻŽāĻžāĻ¨ā§āĻĄā§āĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻžāĻ˛ āĻāĻžāĻ˛ā§ āĻāĻ°āĻŋ:
$ docker-compose -f docker-compose.yml -f docker-compose.db.yml up --scale worker=3
āĻāĻŽāĻžāĻĻā§āĻ° āĻ
āĻ˛ā§āĻāĻŋāĻ āĻ°ā§āĻ¯āĻžāĻ¨ā§āĻĄāĻŽāĻžāĻāĻāĻžāĻ° āĻāĻŋ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§āĻā§, āĻāĻĒāĻ¨āĻŋ āĻāĻāĻā§āĻŽāĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ Data Profiling/Ad Hoc Query
:
āĻŽā§āĻ˛ āĻāĻŋāĻ¨āĻŋāĻ¸āĻāĻŋ āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻāĻĻā§āĻ° āĻāĻžāĻā§ āĻāĻāĻŋ āĻĻā§āĻāĻžāĻ¨ā§ āĻ¨āĻ¯āĻŧ
āĻ¸āĻŽā§āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŋāĻ¤ ETL āĻ¸ā§āĻļāĻ¨ āĻāĻŽāĻŋ āĻāĻ°āĻŦ āĻ¨āĻž, āĻ¸ā§āĻāĻžāĻ¨ā§ āĻ¸āĻŦāĻāĻŋāĻā§āĻ āĻ¤ā§āĻā§āĻ: āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻāĻŋāĻ¤ā§āĻ¤āĻŋ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋ, āĻāĻ¤ā§ āĻāĻāĻāĻŋ āĻāĻŋāĻšā§āĻ¨ āĻ°āĻ¯āĻŧā§āĻā§, āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻ¸āĻā§āĻ āĻĒāĻ°āĻŋāĻāĻžāĻ˛āĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻŦāĻāĻŋāĻā§ āĻŽā§āĻĄāĻŧā§ āĻĢā§āĻ˛āĻŋ āĻāĻŦāĻ āĻāĻāĻ¨ āĻāĻŽāĻ°āĻž āĻāĻāĻŋ āĻāĻ°āĻŋ:
with Session(task_name) as session:
print('Load', session.id, 'started')
# Load worflow
...
session.successful = True
session.loaded_rows = 15
session.py
from sys import stderr
class Session:
"""ETL workflow session
Example:
with Session(task_name) as session:
print(session.id)
session.successful = True
session.loaded_rows = 15
session.comment = 'Well done'
"""
def __init__(self, connection, task_name):
self.connection = connection
self.connection.autocommit = True
self._task_name = task_name
self._id = None
self.loaded_rows = None
self.successful = None
self.comment = None
def __enter__(self):
return self.open()
def __exit__(self, exc_type, exc_val, exc_tb):
if any(exc_type, exc_val, exc_tb):
self.successful = False
self.comment = f'{exc_type}: {exc_val}n{exc_tb}'
print(exc_type, exc_val, exc_tb, file=stderr)
self.close()
def __repr__(self):
return (f'<{self.__class__.__name__} '
f'id={self.id} '
f'task_name="{self.task_name}">')
@property
def task_name(self):
return self._task_name
@property
def id(self):
return self._id
def _execute(self, query, *args):
with self.connection.cursor() as cursor:
cursor.execute(query, args)
return cursor.fetchone()[0]
def _create(self):
query = """
CREATE TABLE IF NOT EXISTS sessions (
id SERIAL NOT NULL PRIMARY KEY,
task_name VARCHAR(200) NOT NULL,
started TIMESTAMPTZ NOT NULL DEFAULT current_timestamp,
finished TIMESTAMPTZ DEFAULT current_timestamp,
successful BOOL,
loaded_rows INT,
comment VARCHAR(500)
);
"""
self._execute(query)
def open(self):
query = """
INSERT INTO sessions (task_name, finished)
VALUES (%s, NULL)
RETURNING id;
"""
self._id = self._execute(query, self.task_name)
print(self, 'opened')
return self
def close(self):
if not self._id:
raise SessionClosedError('Session is not open')
query = """
UPDATE sessions
SET
finished = DEFAULT,
successful = %s,
loaded_rows = %s,
comment = %s
WHERE
id = %s
RETURNING id;
"""
self._execute(query, self.successful, self.loaded_rows,
self.comment, self.id)
print(self, 'closed',
', successful: ', self.successful,
', Loaded: ', self.loaded_rows,
', comment:', self.comment)
class SessionError(Exception):
pass
class SessionClosedError(SessionError):
pass
āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ¸ā§āĻā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¤āĻĨā§āĻ¯ āĻ¸āĻāĻā§āĻ°āĻš āĻāĻ°ā§āĻ¨ āĻāĻŽāĻžāĻĻā§āĻ° āĻĻā§āĻĄāĻŧ āĻļ āĻā§āĻŦāĻŋāĻ˛ āĻĨā§āĻā§āĨ¤ āĻāĻ¸ā§āĻ¨ āĻā§āĻŦ āĻ¨āĻāĻŋāĻ°āĻŦāĻŋāĻšā§āĻ¨ āĻ˛āĻžāĻāĻ¨ā§āĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§ āĻāĻāĻŋ āĻāĻ°āĻŋ:
source_conn = MsSqlHook(mssql_conn_id=src_conn_id, schema=src_schema).get_conn()
query = f"""
SELECT
id, start_time, end_time, type, data
FROM dbo.Orders
WHERE
CONVERT(DATE, start_time) = '{dt}'
"""
df = pd.read_sql_query(query, source_conn)
- āĻāĻāĻāĻŋ āĻšā§āĻā§āĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§ āĻāĻŽāĻ°āĻž āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻĨā§āĻā§ āĻĒāĻžāĻ
pymssql
- āĻ¸āĻāĻ¯ā§āĻ āĻāĻ°ā§āĻ¨ - āĻāĻ¸ā§āĻ¨ āĻ āĻ¨ā§āĻ°ā§āĻ§ā§ āĻ¤āĻžāĻ°āĻŋāĻā§āĻ° āĻāĻāĻžāĻ°ā§ āĻāĻāĻāĻŋ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§āĻ¤āĻž āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻŋ - āĻāĻāĻŋ āĻā§āĻŽāĻĒā§āĻ˛ā§āĻ āĻāĻā§āĻāĻŋāĻ¨ āĻĻā§āĻŦāĻžāĻ°āĻž āĻĢāĻžāĻāĻļāĻ¨ā§ āĻ¨āĻŋāĻā§āĻˇā§āĻĒ āĻāĻ°āĻž āĻšāĻŦā§āĨ¤
- āĻāĻŽāĻžāĻĻā§āĻ° āĻ
āĻ¨ā§āĻ°ā§āĻ§ āĻāĻžāĻāĻ¯āĻŧāĻžāĻ¨ā§
pandas
āĻā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻžāĻŦā§DataFrame
- āĻāĻāĻž āĻāĻŦāĻŋāĻˇā§āĻ¯āĻ¤ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻšāĻŦā§.
āĻāĻŽāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻāĻŋ
{dt}
āĻāĻāĻāĻŋ āĻ āĻ¨ā§āĻ°ā§āĻ§ āĻĒāĻ°āĻžāĻŽāĻŋāĻ¤āĻŋ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§%s
āĻāĻ āĻāĻ¨ā§āĻ¯ āĻ¨āĻ¯āĻŧ āĻ¯ā§ āĻāĻŽāĻŋ āĻāĻāĻāĻ¨ āĻĻā§āĻˇā§āĻ āĻĒāĻŋāĻ¨ā§āĻāĻŋāĻ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻžāĻ°āĻŖpandas
āĻ¸āĻžāĻŽāĻ˛āĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻ¨āĻžpymssql
āĻāĻŦāĻ āĻļā§āĻˇ āĻāĻāĻāĻŋ āĻ¸ā§āĻ˛āĻŋāĻĒparams: List
āĻ¯āĻĻāĻŋāĻ āĻ¸ā§ āĻ¸āĻ¤ā§āĻ¯āĻŋāĻ āĻāĻžāĻ¯āĻŧtuple
.
āĻāĻāĻžāĻĄāĻŧāĻžāĻ āĻŦāĻŋāĻāĻžāĻļāĻāĻžāĻ°ā§ āĻ¨ā§āĻ āĻāĻ°ā§āĻ¨pymssql
āĻ¤āĻžāĻā§ āĻāĻ° āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ āĻ¨āĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ¯āĻŧā§āĻā§, āĻāĻŦāĻ āĻāĻāĻŋ āĻ¸āĻ°āĻžāĻ¨ā§āĻ° āĻ¸āĻŽāĻ¯āĻŧpyodbc
.
āĻāĻ¸ā§āĻ¨ āĻĻā§āĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻĢāĻžāĻāĻļāĻ¨āĻā§āĻ˛āĻŋāĻ° āĻāĻ°ā§āĻā§āĻŽā§āĻ¨ā§āĻāĻā§āĻ˛āĻŋāĻā§ āĻā§ āĻĻāĻŋāĻ¯āĻŧā§ āĻ¸ā§āĻāĻžāĻĢ āĻāĻ°ā§āĻā§:
āĻ¯āĻĻāĻŋ āĻā§āĻ¨ āĻ¤āĻĨā§āĻ¯ āĻ¨āĻž āĻĨāĻžāĻā§, āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻžāĻ˛āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻžāĻ° āĻā§āĻ¨ āĻŽāĻžāĻ¨ā§ āĻ¨ā§āĻāĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻŋ āĻĒā§āĻ°āĻŖ āĻāĻ°āĻž āĻ¸āĻĢāĻ˛ āĻŦāĻŋāĻŦā§āĻāĻ¨āĻž āĻāĻ°āĻžāĻ āĻ āĻĻā§āĻā§āĻ¤āĨ¤ āĻ¤āĻŦā§ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻā§āĻ˛ āĻ¨āĻ¯āĻŧāĨ¤ āĻ-āĻāĻš-āĻāĻš, āĻāĻŋ āĻāĻ°āĻŦ?! āĻāĻŦāĻ āĻāĻāĻžāĻ¨ā§ āĻāĻŋ:
if df.empty:
raise AirflowSkipException('No rows to load')
AirflowSkipException
Airflow āĻā§ āĻŦāĻ˛āĻŦā§ āĻ¯ā§ āĻā§āĻ¨ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻ¨ā§āĻ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŽāĻ°āĻž āĻāĻžāĻāĻāĻŋ āĻāĻĄāĻŧāĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĨ¤ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ā§ āĻ¸āĻŦā§āĻ āĻŦāĻž āĻ˛āĻžāĻ˛ āĻŦāĻ°ā§āĻāĻā§āĻˇā§āĻ¤ā§āĻ° āĻĨāĻžāĻāĻŦā§ āĻ¨āĻž, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻā§āĻ˛āĻžāĻĒā§āĨ¤
āĻāĻ¸ā§āĻ¨ āĻāĻŽāĻžāĻĻā§āĻ° āĻĄā§āĻāĻž āĻāĻ¸ āĻāĻ°āĻŋ āĻāĻāĻžāĻ§āĻŋāĻ āĻāĻ˛āĻžāĻŽ:
df['etl_source'] = src_schema
df['etl_id'] = session.id
df['hash_id'] = hash_pandas_object(df[['etl_source', 'id']])
āĻ¯āĻĨāĻž:
- āĻ¯ā§ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻĨā§āĻā§ āĻāĻŽāĻ°āĻž āĻ āĻ°ā§āĻĄāĻžāĻ° āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛āĻžāĻŽ,
- āĻāĻŽāĻžāĻĻā§āĻ° āĻŦāĻ¨ā§āĻ¯āĻž āĻ¸ā§āĻļāĻ¨ā§āĻ° āĻāĻāĻĄāĻŋ (āĻāĻāĻŋ āĻāĻŋāĻ¨ā§āĻ¨ āĻšāĻŦā§ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻāĻžāĻā§āĻ° āĻāĻ¨ā§āĻ¯),
- āĻāĻ¤ā§āĻ¸ āĻāĻŦāĻ āĻ āĻ°ā§āĻĄāĻžāĻ° āĻāĻāĻĄāĻŋ āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻšā§āĻ¯āĻžāĻļ - āĻ¯āĻžāĻ¤ā§ āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ā§ (āĻ¯ā§āĻāĻžāĻ¨ā§ āĻ¸āĻŦāĻāĻŋāĻā§ āĻāĻāĻāĻŋ āĻā§āĻŦāĻŋāĻ˛ā§ āĻĸā§āĻ˛ā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧ) āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻ āĻ¨āĻ¨ā§āĻ¯ āĻ āĻ°ā§āĻĄāĻžāĻ° āĻāĻāĻĄāĻŋ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤
āĻļā§āĻˇ āĻ§āĻžāĻĒ āĻŦāĻžāĻāĻŋ: āĻāĻžāĻ°ā§āĻāĻŋāĻāĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¸āĻŦāĻāĻŋāĻā§ āĻĸāĻžāĻ˛āĻž. āĻāĻŦāĻ, āĻ āĻĻā§āĻā§āĻ¤āĻāĻžāĻŦā§ āĻ¯āĻĨā§āĻˇā§āĻ, āĻāĻāĻŋ āĻāĻ°āĻžāĻ° āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻĻāĻ°ā§āĻļāĻ¨ā§āĻ¯āĻŧ āĻāĻŦāĻ āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻāĻĒāĻžāĻ¯āĻŧāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻšāĻ˛ CSV āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§!
# Export data to CSV buffer
buffer = StringIO()
df.to_csv(buffer,
index=False, sep='|', na_rep='NUL', quoting=csv.QUOTE_MINIMAL,
header=False, float_format='%.8f', doublequote=False, escapechar='\')
buffer.seek(0)
# Push CSV
target_conn = VerticaHook(vertica_conn_id=target_conn_id).get_conn()
copy_stmt = f"""
COPY {target_table}({df.columns.to_list()})
FROM STDIN
DELIMITER '|'
ENCLOSED '"'
ABORT ON ERROR
NULL 'NUL'
"""
cursor = target_conn.cursor()
cursor.copy(copy_stmt, buffer)
- āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻŦāĻŋāĻļā§āĻˇ āĻ°āĻŋāĻ¸āĻŋāĻāĻžāĻ° āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻāĻŋ
StringIO
. pandas
āĻĻāĻ¯āĻŧāĻž āĻāĻ°ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ°āĻž āĻšāĻŦā§DataFrame
āĻāĻāĻžāĻ°ā§CSV
-āĻ˛āĻžāĻāĻ¨- āĻāĻ¸ā§āĻ¨ āĻāĻāĻāĻŋ āĻšā§āĻ āĻĻāĻŋāĻ¯āĻŧā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻāĻžāĻ°ā§āĻāĻŋāĻāĻžāĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻāĻŋ āĻ¸āĻāĻ¯ā§āĻ āĻā§āĻ˛āĻŋāĨ¤
- āĻāĻŦāĻ āĻāĻāĻ¨ āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§āĻ° āĻ¸āĻžāĻĨā§
copy()
āĻāĻžāĻ°ā§āĻāĻŋāĻāĻžāĻ¯āĻŧ āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ āĻāĻŽāĻžāĻĻā§āĻ° āĻĄā§āĻāĻž āĻĒāĻžāĻ āĻžāĻ¨!
āĻāĻŽāĻ°āĻž āĻĄā§āĻ°āĻžāĻāĻāĻžāĻ°ā§āĻ° āĻāĻžāĻ āĻĨā§āĻā§ āĻ¨ā§āĻŦ āĻāĻ¤āĻā§āĻ˛āĻŋ āĻ˛āĻžāĻāĻ¨ āĻĒā§āĻ°ā§āĻŖ āĻšāĻ¯āĻŧā§āĻā§, āĻāĻŦāĻ āĻ¸ā§āĻļāĻ¨ āĻŽā§āĻ¯āĻžāĻ¨ā§āĻāĻžāĻ°āĻā§ āĻŦāĻ˛āĻŦ āĻ¯ā§ āĻ¸āĻŦāĻāĻŋāĻā§ āĻ āĻŋāĻ āĻāĻā§:
session.loaded_rows = cursor.rowcount
session.successful = True
āĻāĻāĻžāĻ¨ā§āĻ āĻļā§āĻˇ.
āĻŦāĻŋāĻā§āĻ°āĻ¯āĻŧā§, āĻāĻŽāĻ°āĻž āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ˛āĻŋ āĻāĻžāĻ°ā§āĻā§āĻ āĻĒā§āĻ˛ā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋāĨ¤ āĻāĻāĻžāĻ¨ā§ āĻāĻŽāĻŋ āĻ¨āĻŋāĻā§āĻā§ āĻāĻāĻāĻŋ āĻā§āĻ āĻŽā§āĻļāĻŋāĻ¨ā§āĻ° āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻāĻŋāĻ˛āĻžāĻŽ:
create_schema_query = f'CREATE SCHEMA IF NOT EXISTS {target_schema};'
create_table_query = f"""
CREATE TABLE IF NOT EXISTS {target_schema}.{target_table} (
id INT,
start_time TIMESTAMP,
end_time TIMESTAMP,
type INT,
data VARCHAR(32),
etl_source VARCHAR(200),
etl_id INT,
hash_id INT PRIMARY KEY
);"""
create_table = VerticaOperator(
task_id='create_target',
sql=[create_schema_query,
create_table_query],
vertica_conn_id=target_conn_id,
task_concurrency=1,
dag=dag)
āĻāĻŽāĻŋ āĻŦā§āĻ¯āĻžāĻŦāĻšāĻžāĻ° āĻāĻ°āĻāĻŋ
VerticaOperator()
āĻāĻŽāĻŋ āĻāĻāĻāĻŋ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻ¸ā§āĻāĻŋāĻŽāĻž āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻā§āĻŦāĻŋāĻ˛ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŋ (āĻ¯āĻĻāĻŋ āĻ¸ā§āĻā§āĻ˛āĻŋ āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§ āĻŦāĻŋāĻĻā§āĻ¯āĻŽāĻžāĻ¨ āĻ¨āĻž āĻĨāĻžāĻā§, āĻ āĻŦāĻļā§āĻ¯āĻ)āĨ¤ āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻāĻŋāĻ¨āĻŋāĻ¸ āĻ¸āĻ āĻŋāĻāĻāĻžāĻŦā§ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¤āĻž āĻŦā§āĻ¯āĻŦāĻ¸ā§āĻĨāĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧ:
for conn_id, schema in sql_server_ds:
load = PythonOperator(
task_id=schema,
python_callable=workflow,
op_kwargs={
'src_conn_id': conn_id,
'src_schema': schema,
'dt': '{{ ds }}',
'target_conn_id': target_conn_id,
'target_table': f'{target_schema}.{target_table}'},
dag=dag)
create_table >> load
āĻŦā§āĻĻā§āĻ§āĻŋāĻŽāĻžāĻ¨
- āĻāĻā§āĻāĻž, - āĻā§āĻ āĻāĻāĻĻā§āĻ° āĻŦāĻ˛āĻ˛, - āĻāĻāĻ¨ āĻ¤āĻžāĻ āĻ¨āĻž
āĻāĻĒāĻ¨āĻŋ āĻāĻŋ āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻ¯ā§ āĻāĻŽāĻŋ āĻŦāĻ¨ā§āĻ° āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻāĻ¯āĻŧāĻā§āĻāĻ° āĻĒā§āĻ°āĻžāĻŖā§?
āĻā§āĻ˛āĻŋāĻ¯āĻŧāĻž āĻĄā§āĻ¨āĻžāĻ˛ā§āĻĄāĻ¸āĻ¨, āĻĻā§āĻ¯ āĻā§āĻ°ā§āĻĢāĻžāĻ˛ā§
āĻāĻŽāĻŋ āĻŽāĻ¨ā§ āĻāĻ°āĻŋ āĻ¯āĻĻāĻŋ āĻāĻŽāĻžāĻ° āĻ¸āĻšāĻāĻ°ā§āĻŽā§ āĻāĻŦāĻ āĻāĻŽāĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻ¯ā§āĻāĻŋāĻ¤āĻž āĻĨāĻžāĻāĻ¤: āĻā§ āĻĻā§āĻ°ā§āĻ¤ āĻ¸ā§āĻā§āĻ°ā§āĻ¯āĻžāĻ āĻĨā§āĻā§ āĻāĻāĻāĻŋ ETL āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻŦā§ āĻāĻŦāĻ āĻāĻžāĻ˛ā§ āĻāĻ°āĻŦā§: āĻ¤āĻžāĻ°āĻž āĻ¤āĻžāĻĻā§āĻ° SSIS āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻŽāĻžāĻāĻ¸ āĻāĻŦāĻ āĻāĻŽāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ¸āĻš ... āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻĒāĻ°ā§ āĻāĻŽāĻ°āĻž āĻ°āĻā§āĻˇāĻŖāĻžāĻŦā§āĻā§āĻˇāĻŖā§āĻ° āĻ¸āĻšāĻāĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§ āĻ¤ā§āĻ˛āĻ¨āĻž āĻāĻ°āĻŦ ... āĻŦāĻžāĻš, āĻāĻŽāĻŋ āĻŽāĻ¨ā§ āĻāĻ°āĻŋ āĻāĻĒāĻ¨āĻŋ āĻ¸āĻŽā§āĻŽāĻ¤ āĻšāĻŦā§āĻ¨ āĻ¯ā§ āĻāĻŽāĻŋ āĻ¤āĻžāĻĻā§āĻ° āĻ¸āĻŦ āĻĢā§āĻ°āĻ¨ā§āĻā§ āĻĒāĻ°āĻžāĻāĻŋāĻ¤ āĻāĻ°āĻŦ!
āĻ¯āĻĻāĻŋ āĻāĻāĻā§ āĻŦā§āĻļāĻŋ āĻā§āĻ°ā§āĻ¤ā§āĻŦ āĻ¸āĻšāĻāĻžāĻ°ā§, āĻ¤āĻŦā§ āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ - āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽ āĻā§āĻĄ āĻāĻāĻžāĻ°ā§ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ˛āĻŋ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻāĻ°ā§ - āĻāĻŽāĻžāĻ° āĻāĻžāĻ āĻāĻ°ā§āĻā§ āĻ āĻ§āĻŋāĻ āĻāĻ°ā§ āĻāĻ°āĻžāĻŽāĻĻāĻžāĻ¯āĻŧāĻ āĻāĻŦāĻ āĻāĻĒāĻā§āĻā§āĻ¯āĨ¤
āĻĒā§āĻ˛āĻžāĻ-āĻāĻ¨ āĻāĻŦāĻ āĻ¸ā§āĻā§āĻ˛ā§āĻŦāĻŋāĻ˛āĻŋāĻāĻŋāĻ° āĻĒā§āĻ°āĻŦāĻŖāĻ¤āĻž āĻāĻāĻ¯āĻŧ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ āĻāĻ° āĻ¸ā§āĻŽāĻžāĻšā§āĻ¨ āĻāĻā§āĻ¸āĻā§āĻ¨āĻ¸āĻŋāĻŦāĻŋāĻ˛āĻŋāĻāĻŋ, āĻāĻĒāĻ¨āĻžāĻā§ āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ¯ā§āĻā§āĻ¨ā§ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžāĻ° āĻ¸ā§āĻ¯ā§āĻ āĻĻā§āĻ¯āĻŧ: āĻāĻŽāĻ¨āĻāĻŋ āĻĄā§āĻāĻž āĻ¸āĻāĻā§āĻ°āĻš, āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤ āĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻāĻā§āĻ°ā§, āĻāĻŽāĻ¨āĻāĻŋ āĻ°āĻā§āĻ āĻā§āĻā§āĻˇā§āĻĒāĻŖā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ (āĻŽāĻā§āĻāĻ˛ āĻā§āĻ°āĻšā§, āĻāĻ° āĻ āĻŦāĻļā§āĻ¯āĻ)āĨ¤
āĻĒāĻžāĻ°ā§āĻ āĻĢāĻžāĻāĻ¨āĻžāĻ˛, āĻ°ā§āĻĢāĻžāĻ°ā§āĻ¨ā§āĻ¸ āĻāĻŦāĻ āĻ¤āĻĨā§āĻ¯
āĻāĻŽāĻ°āĻž āĻāĻĒāĻ¨āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻāĻā§āĻ°āĻš āĻāĻ°ā§āĻāĻŋ āĻ°ā§āĻ
start_date
. āĻšā§āĻ¯āĻžāĻ, āĻāĻāĻŋ āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻ¸ā§āĻĨāĻžāĻ¨ā§āĻ¯āĻŧ āĻŽā§āĻŽāĨ¤ āĻĄāĻ āĻāĻ° āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻ¯ā§āĻā§āĻ¤āĻŋ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§start_date
āĻ¸āĻŦ āĻĒāĻžāĻ¸. āĻ¸āĻāĻā§āĻˇā§āĻĒā§, āĻ¯āĻĻāĻŋ āĻāĻĒāĻ¨āĻŋ āĻāĻ˛ā§āĻ˛ā§āĻ āĻāĻ°ā§āĻ¨start_date
āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ āĻ¤āĻžāĻ°āĻŋāĻ, āĻāĻŦāĻschedule_interval
- āĻāĻāĻĻāĻŋāĻ¨, āĻ¤āĻžāĻšāĻ˛ā§ āĻĄāĻŋāĻāĻāĻŋ āĻāĻžāĻ˛ āĻļā§āĻ°ā§ āĻšāĻŦā§ āĻāĻā§ āĻ¨āĻžāĨ¤start_date = datetime(2020, 7, 7, 0, 1, 2)
āĻāĻŦāĻ āĻāĻ° āĻā§āĻ¨ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¨ā§āĻāĨ¤
āĻāĻ° āĻ¸āĻžāĻĨā§ āĻ¯ā§āĻā§āĻ¤ āĻāĻ°ā§āĻāĻāĻŋ āĻ°āĻžāĻ¨āĻāĻžāĻāĻŽ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻ°āĻ¯āĻŧā§āĻā§:
Task is missing the start_date parameter
, āĻ¯āĻž āĻĒā§āĻ°āĻžāĻ¯āĻŧāĻļāĻ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻāĻ°ā§ āĻ¯ā§ āĻāĻĒāĻ¨āĻŋ dag āĻ āĻĒāĻžāĻ°ā§āĻāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻŦāĻĻā§āĻ§ āĻāĻ°āĻ¤ā§ āĻā§āĻ˛ā§ āĻā§āĻā§āĻ¨āĨ¤- āĻ¸āĻŦ āĻāĻ āĻŽā§āĻļāĻŋāĻ¨ā§āĨ¤ āĻšā§āĻ¯āĻžāĻ, āĻāĻŦāĻ āĻāĻžāĻāĻāĻŋ (āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ¨āĻŋāĻā§āĻ āĻāĻŦāĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻŦāĻ°āĻŖ), āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻāĻ¯āĻŧā§āĻŦ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°, āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻā§, āĻāĻŦāĻ āĻāĻ°ā§āĻŽā§āĻ°āĻžāĨ¤ āĻāĻŦāĻ āĻāĻāĻž āĻāĻŽāĻ¨āĻāĻŋ āĻāĻžāĻ. āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¸āĻŽāĻ¯āĻŧā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻžāĻĨā§, āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻžāĻā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻŦāĻžāĻĄāĻŧāĻ¤ā§ āĻĨāĻžāĻā§, āĻāĻŦāĻ āĻ¯āĻāĻ¨ PostgreSQL 20 ms āĻāĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§ 5 āĻ¸ā§āĻā§āĻ¨ā§āĻĄā§ āĻ¸ā§āĻāĻā§ āĻ¸āĻžāĻĄāĻŧāĻž āĻĻāĻŋāĻ¤ā§ āĻļā§āĻ°ā§ āĻāĻ°ā§, āĻ¤āĻāĻ¨ āĻāĻŽāĻ°āĻž āĻāĻāĻŋ āĻ¨āĻŋāĻ¯āĻŧā§ āĻāĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛āĻžāĻŽ āĻāĻŦāĻ āĻ¸āĻ°āĻŋāĻ¯āĻŧā§ āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛āĻžāĻŽāĨ¤
- āĻ˛ā§āĻāĻžāĻ˛ āĻāĻā§āĻ¸āĻŋāĻāĻŋāĻāĻāĻ°āĨ¤ āĻšā§āĻ¯āĻžāĻ, āĻāĻŽāĻ°āĻž āĻāĻāĻ¨āĻ āĻāĻāĻŋāĻ° āĻāĻĒāĻ° āĻŦāĻ¸ā§ āĻāĻāĻŋ āĻāĻŦāĻ āĻāĻŽāĻ°āĻž āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§ āĻ āĻ¤āĻ˛ āĻāĻšā§āĻŦāĻ°ā§āĻ° āĻ§āĻžāĻ°ā§ āĻāĻ˛ā§ āĻāĻ¸ā§āĻāĻŋāĨ¤ LocalExecutor āĻāĻāĻ¨ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¯āĻĨā§āĻˇā§āĻ āĻāĻŋāĻ˛, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨ āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ¸ā§āĻā§ āĻ āĻ¨ā§āĻ¤āĻ¤ āĻāĻāĻāĻ¨ āĻāĻ°ā§āĻŽā§ āĻ¨āĻŋāĻ¯āĻŧā§ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŋāĻ¤ āĻāĻ°āĻžāĻ°, āĻāĻŦāĻ CeleryExecutor-āĻ āĻ¯āĻžāĻāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ ā§āĻ° āĻĒāĻ°āĻŋāĻļā§āĻ°āĻŽ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻāĻŦāĻ āĻāĻĒāĻ¨āĻŋ āĻāĻāĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻāĻŋ āĻŽā§āĻļāĻŋāĻ¨ā§ āĻāĻžāĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻāĻ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻāĻŋāĻ° āĻĒāĻ°āĻŋāĻĒā§āĻ°ā§āĻā§āĻˇāĻŋāĻ¤ā§, āĻā§āĻ¨āĻ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§āĻ āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻāĻĒāĻ¨āĻžāĻā§ āĻŦāĻžāĻ§āĻž āĻĻā§āĻ¯āĻŧ āĻ¨āĻž, āĻ¯āĻž "āĻ āĻŦāĻļā§āĻ¯āĻ, āĻ¸āĻ¤āĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻ¨āĻ āĻāĻ¤ā§āĻĒāĻžāĻĻāĻ¨ā§ āĻ¯āĻžāĻŦā§ āĻ¨āĻž!"
- āĻ
-āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ
āĻ¨ā§āĻ¤āĻ°ā§āĻ¨āĻŋāĻ°ā§āĻŽāĻŋāĻ¤ āĻ¸āĻ°āĻā§āĻāĻžāĻŽ:
- āĻ¸āĻāĻ¯ā§āĻ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻļāĻāĻ¸āĻžāĻĒāĻ¤ā§āĻ° āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻ¤ā§,
- SLA āĻŽāĻŋāĻ¸ āĻ¯ā§ āĻāĻžāĻāĻā§āĻ˛ā§ āĻ¸āĻŽāĻ¯āĻŧāĻŽāĻ¤ā§ āĻšāĻ¯āĻŧāĻ¨āĻŋ āĻ¸ā§āĻā§āĻ˛ā§āĻ° āĻāĻŦāĻžāĻŦ āĻĻāĻŋāĻ¤ā§,
- xcom āĻŽā§āĻāĻžāĻĄā§āĻāĻž āĻŦāĻŋāĻ¨āĻŋāĻŽāĻ¯āĻŧā§āĻ° āĻāĻ¨ā§āĻ¯ (āĻāĻŽāĻŋ āĻŦāĻ˛āĻ˛āĻžāĻŽ āĻŽā§āĻāĻžāĻĄā§āĻāĻž!) āĻĄā§āĻ āĻāĻžāĻā§āĻ° āĻŽāĻ§ā§āĻ¯ā§āĨ¤
- āĻŽā§āĻ˛ āĻ āĻĒāĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°. āĻāĻ¯āĻŧā§āĻ˛ āĻāĻŽāĻŋ āĻāĻŋ āĻŦāĻ˛āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨? āĻĒāĻ¤āĻŋāĻ¤ āĻāĻžāĻā§āĻ° āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻ¤āĻ°ā§āĻāĻ¤āĻž āĻ¸ā§āĻ āĻāĻĒ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛āĨ¤ āĻāĻāĻ¨ āĻāĻŽāĻžāĻ° āĻāĻžāĻ Gmail-āĻ Airflow āĻĨā§āĻā§ >90k āĻāĻŽā§āĻ˛ āĻāĻā§, āĻāĻŦāĻ āĻāĻ¯āĻŧā§āĻŦ āĻŽā§āĻāĻ˛ ââāĻŽāĻā§āĻ˛ āĻāĻāĻŦāĻžāĻ°ā§ 100 āĻāĻŋāĻ°āĻ āĻŦā§āĻļāĻŋ āĻĒāĻŋāĻ āĻāĻĒ āĻāĻ°āĻ¤ā§ āĻāĻŦāĻ āĻŽā§āĻāĻ¤ā§ āĻ āĻ¸ā§āĻŦā§āĻāĻžāĻ° āĻāĻ°ā§āĨ¤
āĻāĻ°ā§ āĻā§āĻˇāĻ¤āĻŋ:
Apache Airflow Pitfails
āĻāĻ°āĻ āĻ āĻā§āĻŽā§āĻļāĻ¨ āĻā§āĻ˛
āĻāĻŽāĻžāĻĻā§āĻ° āĻšāĻžāĻ¤ āĻĻāĻŋāĻ¯āĻŧā§ āĻ¨āĻ¯āĻŧ āĻāĻŽāĻžāĻĻā§āĻ° āĻŽāĻžāĻĨāĻž āĻĻāĻŋāĻ¯āĻŧā§ āĻāĻ°āĻ āĻŦā§āĻļāĻŋ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻŋ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤ āĻāĻ°ā§āĻā§:
āĻŦāĻŋāĻļā§āĻ°āĻžāĻŽ āĻāĻĒāĻŋāĻāĻ - āĻ¤āĻžāĻ° āĻāĻāĻ¨āĻ āĻĒāĻ°ā§āĻā§āĻˇāĻžāĻŽā§āĻ˛āĻ āĻŽāĻ°ā§āĻ¯āĻžāĻĻāĻž āĻ°āĻ¯āĻŧā§āĻā§, āĻ¯āĻž āĻ¤āĻžāĻā§ āĻāĻžāĻ āĻāĻ°āĻ¤ā§ āĻŦāĻžāĻ§āĻž āĻĻā§āĻ¯āĻŧ āĻ¨āĻžāĨ¤ āĻāĻāĻŋāĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§, āĻāĻĒāĻ¨āĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻĄā§āĻ¯āĻžāĻ āĻāĻŦāĻ āĻāĻžāĻ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻ¤āĻĨā§āĻ¯ āĻĒā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻ¨āĻž, āĻ¤āĻŦā§ āĻāĻāĻāĻŋ āĻĄā§āĻ¯āĻžāĻ āĻŦāĻ¨ā§āĻ§/āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§, āĻāĻāĻāĻŋ DAG āĻ°āĻžāĻ¨ āĻŦāĻž āĻāĻāĻāĻŋ āĻĒā§āĻ˛ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ā§ˇCLI - āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻ˛āĻžāĻāĻ¨ā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻ āĻ¨ā§āĻ āĻā§āĻ˛ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻ¯āĻŧ āĻ¯ā§āĻā§āĻ˛ā§ āĻļā§āĻ§ā§ WebUI āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻ āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻāĻ¨āĻ āĻ¨āĻ¯āĻŧ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻ¤ āĻ āĻ¨ā§āĻĒāĻ¸ā§āĻĨāĻŋāĻ¤āĨ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻ¸ā§āĻŦāĻ°ā§āĻĒ:backfill
āĻāĻžāĻ¸ā§āĻ āĻĻā§āĻˇā§āĻāĻžāĻ¨ā§āĻ¤ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻāĻ°āĻŽā§āĻ āĻāĻ°āĻ¤ā§ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨.
āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻāĻ°āĻž āĻāĻ¸ā§ āĻŦāĻ˛āĻ˛ā§āĻ¨: âāĻāĻŦāĻ āĻāĻŽāĻ°ā§āĻĄ, āĻāĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ°ā§ 1 āĻĨā§āĻā§ 13 āĻ¤āĻžāĻ°āĻŋāĻā§āĻ° āĻĄā§āĻāĻžāĻ¤ā§ āĻāĻĒāĻ¨āĻŋ āĻāĻā§āĻŦāĻžāĻā§ āĻāĻĨāĻž āĻŦāĻ˛ā§āĻā§āĻ¨! āĻ āĻŋāĻ āĻāĻ°, āĻ āĻŋāĻ āĻāĻ°, āĻ āĻŋāĻ āĻāĻ°, āĻ āĻŋāĻ āĻāĻ°!" āĻāĻŦāĻ āĻāĻĒāĻ¨āĻŋ āĻ¯ā§āĻŽāĻ¨ āĻāĻāĻāĻŋ āĻšāĻŦ:airflow backfill -s '2020-01-01' -e '2020-01-13' orders
- āĻŦā§āĻ¸ āĻ¸āĻžāĻ°ā§āĻāĻŋāĻ¸:
initdb
,resetdb
,upgradedb
,checkdb
. run
, āĻ¯āĻž āĻāĻĒāĻ¨āĻžāĻā§ āĻāĻāĻāĻŋ āĻāĻ¨āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻ¸ āĻāĻžāĻ¸ā§āĻ āĻāĻžāĻ˛āĻžāĻ¨ā§āĻ° āĻāĻŦāĻ āĻāĻŽāĻ¨āĻāĻŋ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¤āĻžāĻ° āĻāĻĒāĻ° āĻ¸ā§āĻā§āĻ° āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤ āĻ¤āĻžāĻāĻžāĻĄāĻŧāĻž, āĻāĻĒāĻ¨āĻŋ āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻāĻŋ āĻāĻžāĻ˛āĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨LocalExecutor
, āĻāĻŽāĻ¨āĻāĻŋ āĻ¯āĻĻāĻŋ āĻāĻĒāĻ¨āĻžāĻ° āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻā§āĻ˛āĻžāĻ¸ā§āĻāĻžāĻ° āĻĨāĻžāĻā§āĨ¤- āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻāĻāĻ āĻāĻŋāĻ¨āĻŋāĻ¸ āĻāĻ°ā§
test
, āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻāĻžāĻāĻāĻŋāĻ¤ā§āĻ āĻāĻŋāĻā§āĻ āĻ˛ā§āĻā§ āĻ¨āĻžāĨ¤ connections
āĻļā§āĻ˛ āĻĨā§āĻā§ āĻ¸āĻāĻ¯ā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤
āĻĒāĻžāĻāĻĨāĻ¨ āĻāĻĒāĻŋāĻāĻ - āĻŽāĻŋāĻĨāĻ¸ā§āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻ°āĻžāĻ° āĻāĻāĻāĻŋ āĻŦāĻ°āĻ āĻšāĻžāĻ°ā§āĻĄāĻā§āĻ° āĻāĻĒāĻžāĻ¯āĻŧ, āĻ¯āĻž āĻĒā§āĻ˛āĻžāĻāĻāĻ¨āĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻĻā§āĻĻāĻŋāĻˇā§āĻ, āĻāĻŦāĻ āĻ¸āĻžāĻŽāĻžāĻ¨ā§āĻ¯ āĻšāĻžāĻ¤ āĻĻāĻŋāĻ¯āĻŧā§ āĻāĻ¤ā§ āĻāĻžāĻāĻā§āĻ¨āĻŋ āĻ¨āĻžāĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¯ā§āĻ¤ā§ āĻŦāĻžāĻ§āĻž āĻĻā§āĻŦā§ āĻā§/home/airflow/dags
, āĻāĻžāĻ˛āĻžāĻ¨ipython
āĻāĻŦāĻ āĻāĻžāĻ°āĻĒāĻžāĻļā§ āĻāĻāĻžāĻāĻŋāĻā§āĻĄāĻŧāĻŋ āĻļā§āĻ°ā§? āĻāĻĒāĻ¨āĻŋ, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ āĻā§āĻĄ āĻ¸āĻš āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¸āĻāĻ¯ā§āĻ āĻ°āĻĒā§āĻ¤āĻžāĻ¨āĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨:from airflow import settings from airflow.models import Connection fields = 'conn_id conn_type host port schema login password extra'.split() session = settings.Session() for conn in session.query(Connection).order_by(Connection.conn_id): d = {field: getattr(conn, field) for field in fields} print(conn.conn_id, '=', d)
- āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻŽā§āĻāĻžāĻĄā§āĻāĻžāĻŦā§āĻ¸ā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻāĻ¯ā§āĻ āĻāĻ°āĻž āĻšāĻā§āĻā§āĨ¤ āĻāĻŽāĻŋ āĻāĻāĻŋāĻ¤ā§ āĻ˛ā§āĻāĻžāĻ° āĻĒāĻ°āĻžāĻŽāĻ°ā§āĻļ āĻĻāĻŋāĻ āĻ¨āĻž, āĻ¤āĻŦā§ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻŽā§āĻā§āĻ°āĻŋāĻā§āĻ¸ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻžāĻ¸ā§āĻ āĻ¸ā§āĻā§āĻ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯ā§ āĻā§āĻ¨āĻ API āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžāĻ° āĻā§āĻ¯āĻŧā§ āĻ
āĻ¨ā§āĻ āĻĻā§āĻ°ā§āĻ¤ āĻāĻŦāĻ āĻ¸āĻšāĻ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤
āĻāĻ¸ā§āĻ¨ āĻāĻŽāĻ°āĻž āĻŦāĻ˛āĻŋ āĻ¯ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻžāĻāĻ āĻ āĻĻāĻŽā§āĻ¯ āĻ¨āĻ¯āĻŧ, āĻ¤āĻŦā§ āĻ¸ā§āĻā§āĻ˛āĻŋ āĻāĻāĻ¨āĻ āĻāĻāĻ¨āĻ āĻĒāĻĄāĻŧā§ āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻāĻŦāĻ āĻāĻāĻŋ āĻ¸ā§āĻŦāĻžāĻāĻžāĻŦāĻŋāĻāĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻŦā§āĻ˛āĻā§āĻ āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§āĻ āĻ¸āĻ¨ā§āĻĻā§āĻšāĻāĻ¨āĻ, āĻāĻŦāĻ āĻāĻāĻŋ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨āĨ¤
āĻāĻ¸āĻāĻŋāĻāĻāĻ˛ āĻ¸āĻžāĻŦāĻ§āĻžāĻ¨!
WITH last_executions AS ( SELECT task_id, dag_id, execution_date, state, row_number() OVER ( PARTITION BY task_id, dag_id ORDER BY execution_date DESC) AS rn FROM public.task_instance WHERE execution_date > now() - INTERVAL '2' DAY ), failed AS ( SELECT task_id, dag_id, execution_date, state, CASE WHEN rn = row_number() OVER ( PARTITION BY task_id, dag_id ORDER BY execution_date DESC) THEN TRUE END AS last_fail_seq FROM last_executions WHERE state IN ('failed', 'up_for_retry') ) SELECT task_id, dag_id, count(last_fail_seq) AS unsuccessful, count(CASE WHEN last_fail_seq AND state = 'failed' THEN 1 END) AS failed, count(CASE WHEN last_fail_seq AND state = 'up_for_retry' THEN 1 END) AS up_for_retry FROM failed GROUP BY task_id, dag_id HAVING count(last_fail_seq) > 0
āĻ°ā§āĻĢāĻžāĻ°ā§āĻ¨ā§āĻ¸
āĻāĻŦāĻ āĻ āĻŦāĻļā§āĻ¯āĻ, āĻā§āĻāĻ˛ āĻāĻ¸ā§āĻ¯ā§ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻĻāĻļāĻāĻŋ āĻ˛āĻŋāĻā§āĻ āĻāĻŽāĻžāĻ° āĻŦā§āĻāĻŽāĻžāĻ°ā§āĻ āĻĨā§āĻā§ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻĢā§āĻ˛ā§āĻĄāĻžāĻ°ā§āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§āĨ¤
āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻĄāĻā§āĻŽā§āĻ¨ā§āĻā§āĻļāĻ¨ - āĻ āĻŦāĻļā§āĻ¯āĻ āĻ āĻĢāĻŋāĻ¸ āĻĻāĻŋāĻ¯āĻŧā§ āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻĄāĻā§āĻŽā§āĻ¨ā§āĻā§āĻļāĻ¨, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļāĻžāĻŦāĻ˛ā§ āĻā§ āĻĒāĻĄāĻŧā§?āĻ¸ā§āĻ°āĻž āĻ āĻ¨ā§āĻļā§āĻ˛āĻ¨ - āĻ āĻŋāĻ āĻāĻā§, āĻ āĻ¨ā§āĻ¤āĻ¤ āĻ¨āĻŋāĻ°ā§āĻŽāĻžāĻ¤āĻžāĻĻā§āĻ° āĻāĻžāĻ āĻĨā§āĻā§ āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ āĻĒāĻĄāĻŧā§āĻ¨āĨ¤āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ UI - āĻāĻā§āĻŦāĻžāĻ°ā§ āĻļā§āĻ°ā§: āĻāĻŦāĻŋāĻ¤ā§ āĻāĻāĻāĻžāĻ° āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸Apache Airflow āĻāĻ° āĻŽā§āĻ˛ āĻ§āĻžāĻ°āĻŖāĻž āĻŦā§āĻāĻž - āĻŽā§āĻ˛āĻŋāĻ āĻ§āĻžāĻ°āĻŖāĻžāĻā§āĻ˛āĻŋ āĻāĻžāĻ˛āĻāĻžāĻŦā§ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§, āĻ¯āĻĻāĻŋ (āĻšāĻ āĻžā§!) āĻāĻĒāĻ¨āĻŋ āĻāĻŽāĻžāĻ° āĻāĻžāĻ āĻĨā§āĻā§ āĻāĻŋāĻā§ āĻŦā§āĻāĻ¤ā§ āĻ¨āĻž āĻĒāĻžāĻ°ā§āĻ¨āĨ¤āĻ¤āĻŋāĻ¯āĻŧāĻžāĻ¨āĻ˛āĻ āĻāĻ° āĻŦā§āĻ˛āĻ â āĻāĻŋāĻāĻžāĻŦā§ āĻāĻāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°/āĻā§āĻ˛āĻžāĻ¸ā§āĻāĻžāĻ° āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻšāĻ¯āĻŧ āĻ¤āĻžāĻ° āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļāĻŋāĻāĻž - āĻāĻāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻā§āĻ˛āĻžāĻ¸ā§āĻāĻžāĻ° āĻ¸ā§āĻ āĻāĻĒ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ¸āĻāĻā§āĻˇāĻŋāĻĒā§āĻ¤ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļāĻŋāĻāĻžāĨ¤Lyft āĻ Apache āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻ˛āĻā§ - āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻāĻāĻ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§, āĻ¸āĻŽā§āĻāĻŦāĻ¤ āĻāĻ°āĻ āĻāĻ¨ā§āĻˇā§āĻ āĻžāĻ¨āĻŋāĻāĻ¤āĻž āĻāĻŦāĻ āĻāĻŽ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻāĻžāĻĄāĻŧāĻžāĨ¤āĻāĻŋāĻāĻžāĻŦā§ Apache Airflow āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻāĻ°ā§āĻŽā§āĻĻā§āĻ° āĻāĻžāĻāĻ°āĻŋ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻāĻ°ā§ - āĻ¸ā§āĻ˛āĻžāĻ°āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻ¯ā§āĻā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧā§āĨ¤Apache āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĻ¤ā§ DAG āĻ˛ā§āĻāĻžāĻ° āĻ¸ā§āĻ°āĻž āĻ āĻ¨ā§āĻļā§āĻ˛āĻ¨ - āĻāĻžāĻā§āĻ° āĻ āĻĻāĻŽā§āĻ¯āĻ¤āĻž āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§, āĻ¤āĻžāĻ°āĻŋāĻā§āĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§ āĻāĻāĻĄāĻŋ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ˛ā§āĻĄ āĻāĻ°āĻž, āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ°, āĻĢāĻžāĻāĻ˛ā§āĻ° āĻāĻžāĻ āĻžāĻŽā§ āĻāĻŦāĻ āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ āĻāĻŋāĻ¨āĻŋāĻ¸āĨ¤āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĻ¤ā§ āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¤āĻž āĻĒāĻ°āĻŋāĻāĻžāĻ˛āĻ¨āĻž āĻāĻ°āĻž - āĻāĻžāĻ āĻāĻŦāĻ āĻā§āĻ°āĻŋāĻāĻžāĻ° āĻ¨āĻŋāĻ¯āĻŧāĻŽā§āĻ° āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¤āĻž, āĻ¯āĻž āĻāĻŽāĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻĒāĻžāĻ¸ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ˛ā§āĻ˛ā§āĻ āĻāĻ°ā§āĻāĻŋāĨ¤āĻŦāĻžāĻ¯āĻŧā§āĻĒā§āĻ°āĻŦāĻžāĻš: āĻ¯āĻāĻ¨ āĻāĻĒāĻ¨āĻžāĻ° DAG āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§āĻā§āĻ° āĻĒāĻŋāĻāĻ¨ā§ āĻĨāĻžāĻā§ - āĻāĻŋāĻāĻžāĻŦā§ āĻļāĻŋāĻĄāĻŋāĻāĻ˛āĻžāĻ°ā§āĻ° āĻāĻŋāĻā§ "āĻāĻĻā§āĻĻā§āĻļā§āĻ¯ āĻ āĻ¨ā§āĻ¯āĻžāĻ¯āĻŧā§ āĻāĻžāĻ" āĻāĻžāĻāĻŋāĻ¯āĻŧā§ āĻāĻ āĻ¤ā§ āĻšāĻ¯āĻŧ, āĻšāĻžāĻ°āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻĄā§āĻāĻž āĻ˛ā§āĻĄ āĻāĻ°āĻ¤ā§ āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻāĻžāĻāĻā§āĻ˛āĻŋāĻā§ āĻ āĻā§āĻ°āĻžāĻ§āĻŋāĻāĻžāĻ° āĻĻāĻŋāĻ¤ā§ āĻšāĻ¯āĻŧāĨ¤Apache Airflow āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻĻāĻ°āĻāĻžāĻ°ā§ SQL āĻĒā§āĻ°āĻļā§āĻ¨ â āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻŽā§āĻāĻžāĻĄā§āĻāĻžāĻ¤ā§ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻāĻ¸āĻāĻŋāĻāĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨āĨ¤Apache Airflow āĻāĻ° āĻ¸āĻžāĻĨā§ āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻĢā§āĻ˛ā§ āĻĄā§āĻā§āĻ˛āĻĒ āĻāĻ°āĻž āĻļā§āĻ°ā§ āĻāĻ°ā§āĻ¨ - āĻāĻāĻāĻŋ āĻāĻžāĻ¸ā§āĻāĻŽ āĻ¸ā§āĻ¨ā§āĻ¸āĻ° āĻ¤ā§āĻ°āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻāĻāĻŋ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻŦāĻŋāĻāĻžāĻ āĻāĻā§āĨ¤Presto āĻāĻŦāĻ Airflow āĻ¸āĻš AWS-āĻ Fetchr āĻĄā§āĻāĻž āĻ¸āĻžāĻ¯āĻŧā§āĻ¨ā§āĻ¸ āĻāĻ¨āĻĢā§āĻ°āĻž āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž â āĻĄā§āĻāĻž āĻ¸āĻžāĻ¯āĻŧā§āĻ¨ā§āĻ¸ā§āĻ° āĻāĻ¨ā§āĻ¯ AWS-āĻ āĻāĻāĻāĻŋ āĻĒāĻ°āĻŋāĻāĻžāĻ āĻžāĻŽā§ āĻ¨āĻŋāĻ°ā§āĻŽāĻžāĻŖā§āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧā§ āĻāĻāĻāĻŋ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ āĻ¸āĻāĻā§āĻˇāĻŋāĻĒā§āĻ¤ āĻ¨ā§āĻāĨ¤āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻĄāĻŋāĻāĻāĻŋ āĻĄāĻŋāĻŦāĻžāĻ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻā§āĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ 7āĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¤ā§āĻ°ā§āĻāĻŋā§ˇ - āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻā§āĻ˛ (āĻ¯āĻāĻ¨ āĻā§āĻ āĻāĻāĻ¨āĻ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļāĻžāĻŦāĻ˛ā§ āĻĒāĻĄāĻŧā§ āĻ¨āĻž)āĨ¤Apache Airflow āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻĒāĻžāĻ¸āĻāĻ¯āĻŧāĻžāĻ°ā§āĻĄ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻŦāĻ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ āĻāĻ°ā§āĻ¨ - āĻšāĻžāĻ¸ā§āĻ¨ āĻ˛ā§āĻā§āĻ°āĻž āĻā§āĻāĻžāĻŦā§ āĻĒāĻžāĻ¸āĻāĻ¯āĻŧāĻžāĻ°ā§āĻĄ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°ā§, āĻ¯āĻĻāĻŋāĻ āĻāĻĒāĻ¨āĻŋ āĻā§āĻŦāĻ˛ āĻ¸āĻāĻ¯ā§āĻāĻā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ā§ˇāĻĒāĻžāĻāĻĨāĻ¨ āĻāĻŦāĻ āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻ° āĻā§āĻ¨ - āĻ āĻ¨ā§āĻ¤āĻ°ā§āĻ¨āĻŋāĻšāĻŋāĻ¤ DAG āĻĢāĻ°āĻāĻ¯āĻŧāĻžāĻ°ā§āĻĄāĻŋāĻ, āĻĢāĻžāĻāĻļāĻ¨ā§ āĻāĻ¨āĻā§āĻā§āĻ¸āĻ āĻĨā§āĻ°ā§āĻ¯āĻŧāĻŋāĻ, āĻāĻŦāĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻāĻ°āĻ¤āĻž āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§, āĻāĻŦāĻ āĻāĻžāĻ¸ā§āĻ āĻ˛āĻā§āĻ āĻāĻĄāĻŧāĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§āĻāĨ¤āĻŦāĻžāĻ¯āĻŧā§āĻĒā§āĻ°āĻŦāĻžāĻš: āĻāĻŽ āĻĒāĻ°āĻŋāĻāĻŋāĻ¤ āĻāĻŋāĻĒāĻ¸, āĻā§āĻļāĻ˛ āĻāĻŦāĻ āĻ¸āĻ°ā§āĻŦā§āĻ¤ā§āĻ¤āĻŽ āĻ āĻ¨ā§āĻļā§āĻ˛āĻ¨ - āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§default arguments
иparams
āĻā§āĻŽāĻĒā§āĻ˛ā§āĻ, āĻ¸ā§āĻāĻ¸āĻžāĻĨā§ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ āĻāĻŦāĻ āĻ¸āĻāĻ¯ā§āĻāĻā§āĻ˛āĻŋāĻ¤ā§āĨ¤āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻ¸āĻŋāĻĄāĻŋāĻāĻ˛āĻžāĻ° āĻĒā§āĻ°ā§āĻĢāĻžāĻāĻ˛āĻŋāĻ - āĻĒāĻ°āĻŋāĻāĻ˛ā§āĻĒāĻ¨āĻžāĻāĻžāĻ°ā§ āĻā§āĻāĻžāĻŦā§ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ 2.0 āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤āĻŋ āĻ¨āĻŋāĻā§āĻā§āĻ¨ āĻ¸ā§ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻāĻāĻŋ āĻāĻ˛ā§āĻĒāĨ¤āĻĄāĻāĻžāĻ°-āĻāĻŽā§āĻĒā§āĻā§ 3 āĻ¸ā§āĻ˛āĻžāĻ°āĻŋ āĻāĻ°ā§āĻŽā§āĻĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻ ā§āĻ¯āĻžāĻĒāĻžāĻāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ - āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻ˛āĻžāĻ¸ā§āĻāĻžāĻ° āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻāĻāĻŋ āĻ¸āĻžāĻŽāĻžāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻžāĻ¨ā§ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§docker-compose
.āĻŦāĻžāĻ¯āĻŧā§āĻĒā§āĻ°āĻŦāĻžāĻšā§āĻ° āĻĒā§āĻ°āĻ¸āĻā§āĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ 4 āĻā§āĻŽāĻĒā§āĻ˛ā§āĻāĻŋāĻ āĻāĻžāĻ¸ā§āĻ - āĻā§āĻŽāĻĒā§āĻ˛ā§āĻ āĻāĻŦāĻ āĻĒā§āĻ°āĻ¸āĻā§āĻ āĻĢāĻ°āĻāĻ¯āĻŧāĻžāĻ°ā§āĻĄāĻŋāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻ¤āĻŋāĻļā§āĻ˛ āĻāĻžāĻāĨ¤āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§āĻ¤ā§ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻŦāĻŋāĻā§āĻāĻĒā§āĻ¤āĻŋ â āĻŽā§āĻ˛ āĻāĻŦāĻ āĻ¸ā§āĻ˛ā§āĻ¯āĻžāĻā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āĻāĻŦāĻ āĻāĻžāĻ¸ā§āĻāĻŽ āĻŦāĻŋāĻā§āĻāĻĒā§āĻ¤āĻŋāĨ¤āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§ āĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻļāĻĒ: āĻā§āĻ°āĻžāĻ āĻāĻžāĻĄāĻŧāĻž āĻāĻāĻŋāĻ˛ āĻĄāĻŋāĻāĻāĻŋ - āĻŦā§āĻ°āĻžāĻā§āĻāĻŋāĻ āĻāĻžāĻ¸ā§āĻ, āĻŽā§āĻ¯āĻžāĻā§āĻ°ā§ āĻāĻŦāĻ āĻāĻā§āĻ¸āĻāĻŽāĨ¤
āĻāĻŦāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§ āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻ˛āĻŋāĻā§āĻāĻā§āĻ˛āĻŋ:
āĻŽā§āĻ¯āĻžāĻā§āĻ°ā§ āĻ°ā§āĻĢāĻžāĻ°ā§āĻ¨ā§āĻ¸ - āĻā§āĻŽāĻĒā§āĻ˛ā§āĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻĨāĻžāĻ¨āĻ§āĻžāĻ°āĻ āĻāĻĒāĻ˛āĻŦā§āĻ§āĨ¤āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻā§āĻˇāĻ¤āĻŋ - āĻŦāĻžāĻ¯āĻŧā§āĻĒā§āĻ°āĻŦāĻžāĻš - āĻĄā§āĻ¯āĻžāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻā§āĻ˛āĨ¤puckel/docker-airflow: Docker Apache Airflow -docker-compose
āĻĒāĻ°ā§āĻā§āĻˇāĻž, āĻĄāĻŋāĻŦāĻžāĻāĻŋāĻ āĻāĻŦāĻ āĻāĻ°āĻ āĻ āĻ¨ā§āĻ āĻāĻŋāĻā§āĻ° āĻāĻ¨ā§āĻ¯āĨ¤python-telegram-bot/python-telegram-bot: āĻāĻŽāĻ°āĻž āĻāĻĒāĻ¨āĻžāĻā§ āĻāĻāĻāĻŋ āĻŽā§āĻĄāĻŧāĻ āĻŦāĻžāĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋ āĻ¯āĻž āĻāĻĒāĻ¨āĻŋ āĻ āĻ¸ā§āĻŦā§āĻāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŦā§āĻ¨ āĻ¨āĻž â āĻā§āĻ˛āĻŋāĻā§āĻ°āĻžāĻŽ REST API-āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻĒāĻžāĻāĻĨāĻ¨ āĻ°âā§āĻ¯āĻžāĻĒāĻžāĻ°āĨ¤
āĻāĻ¤ā§āĻ¸: www.habr.com