āĻ…ā§āĻ¯āĻžāĻĒāĻžāĻšāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹: āĻ‡āĻŸāĻŋāĻāĻ˛āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ¸āĻšāĻœ āĻ•āĻ°āĻž

āĻšāĻžāĻ‡, āĻ†āĻŽāĻŋ āĻĻāĻŋāĻŽāĻŋāĻ¤ā§āĻ°āĻŋ āĻ˛āĻ—āĻ­āĻŋāĻ¨ā§‡āĻ™ā§āĻ•ā§‹ - āĻ­ā§‡āĻœā§‡āĻŸ āĻ—ā§āĻ°ā§āĻĒ āĻ…āĻĢ āĻ•ā§‹āĻŽā§āĻĒāĻžāĻ¨āĻŋāĻ° āĻŦāĻŋāĻļā§āĻ˛ā§‡āĻˇāĻŖ āĻŦāĻŋāĻ­āĻžāĻ—ā§‡āĻ° āĻĄā§‡āĻŸāĻž āĻ‡āĻžā§āĻœāĻŋāĻ¨āĻŋāĻ¯āĻŧāĻžāĻ°āĨ¤

āĻ†āĻŽāĻŋ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ ETL āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ—ā§āĻ˛āĻŋ āĻŦāĻŋāĻ•āĻžāĻļā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻĻā§āĻ°ā§āĻĻāĻžāĻ¨ā§āĻ¤ āĻ¸āĻ°āĻžā§āĻœāĻžāĻŽ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻŦāĻ˛āĻŦ - āĻ…ā§āĻ¯āĻžāĻĒāĻžāĻšāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹āĨ¤ āĻ¤āĻŦā§‡ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹ āĻāĻ¤āĻ‡ āĻŦāĻšā§āĻŽā§āĻ–ā§€ āĻāĻŦāĻ‚ āĻŦāĻšā§āĻŽā§āĻ–ā§€ āĻ¯ā§‡ āĻ†āĻĒāĻ¨āĻŋ āĻĄā§‡āĻŸāĻž āĻĒā§āĻ°āĻŦāĻžāĻšā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻœāĻĄāĻŧāĻŋāĻ¤ āĻ¨āĻž āĻšāĻ˛ā§‡āĻ“ āĻāĻŸāĻŋāĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ˜āĻ¨āĻŋāĻˇā§āĻ āĻ­āĻžāĻŦā§‡ āĻĻā§‡āĻ–ā§‡ āĻ¨ā§‡āĻ“āĻ¯āĻŧāĻž āĻ‰āĻšāĻŋāĻ¤, āĻ¤āĻŦā§‡ āĻĒāĻ°ā§āĻ¯āĻžāĻ¯āĻŧāĻ•ā§āĻ°āĻŽā§‡ āĻ¯ā§‡ āĻ•ā§‹āĻ¨āĻ“ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻšāĻžāĻ˛ā§ āĻ•āĻ°āĻž āĻāĻŦāĻ‚ āĻ¤āĻžāĻĻā§‡āĻ° āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ āĻ¨āĻŋāĻ°ā§€āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤

āĻāĻŦāĻ‚ āĻšā§āĻ¯āĻžāĻ, āĻ†āĻŽāĻŋ āĻ•ā§‡āĻŦāĻ˛ āĻŦāĻ˛āĻŦ āĻ¨āĻž, āĻ¤āĻŦā§‡ āĻĻā§‡āĻ–āĻžāĻŦ: āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻŸāĻŋāĻ¤ā§‡ āĻĒā§āĻ°āĻšā§āĻ° āĻ•ā§‹āĻĄ, āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻ¨āĻļāĻŸ āĻāĻŦāĻ‚ āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤

āĻ…ā§āĻ¯āĻžāĻĒāĻžāĻšāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹: āĻ‡āĻŸāĻŋāĻāĻ˛āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ¸āĻšāĻœ āĻ•āĻ°āĻž
āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹ / āĻ‰āĻ‡āĻ•āĻŋāĻŽāĻŋāĻĄāĻŋāĻ¯āĻŧāĻž āĻ•āĻŽāĻ¨ā§āĻ¸ āĻļāĻŦā§āĻĻāĻŸāĻŋ āĻ—ā§āĻ—āĻ˛ āĻ•āĻ°āĻ˛ā§‡ āĻ†āĻĒāĻ¨āĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻ¤ āĻ¯āĻž āĻĻā§‡āĻ–āĻ¤ā§‡ āĻĒāĻžāĻ¨

āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§ āĻ¸ā§‚āĻšāĻŋ

āĻ­ā§‚āĻŽāĻŋāĻ•āĻž

āĻ…ā§āĻ¯āĻžāĻĒāĻžāĻšāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹ āĻ āĻŋāĻ• āĻœā§āĻ¯āĻžāĻ™ā§āĻ—ā§‹āĻ° āĻŽāĻ¤ā§‹:

  • āĻĒāĻžāĻ‡āĻĨāĻ¨ā§‡ āĻ˛ā§‡āĻ–āĻž
  • āĻāĻ•āĻŸāĻŋ āĻŽāĻšāĻžāĻ¨ āĻ…ā§āĻ¯āĻžāĻĄāĻŽāĻŋāĻ¨ āĻĒā§āĻ¯āĻžāĻ¨ā§‡āĻ˛ āĻ†āĻ›ā§‡,
  • āĻ…āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸāĻ•āĻžāĻ˛ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¸āĻžāĻ°āĻŖāĻ¯ā§‹āĻ—ā§āĻ¯

- āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ­āĻžāĻ˛, āĻāĻŦāĻ‚ āĻāĻŸāĻŋ āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ­āĻŋāĻ¨ā§āĻ¨ āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ¯āĻĨāĻž (āĻ¯ā§‡āĻŽāĻ¨ āĻāĻŸāĻŋ āĻ•ā§āĻ¯āĻžāĻŸā§‡āĻ° āĻ†āĻ—ā§‡ āĻ˛ā§‡āĻ–āĻž āĻ†āĻ›ā§‡):

  • āĻ¸ā§€āĻŽāĻžāĻšā§€āĻ¨ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻ• āĻŽā§‡āĻļāĻŋāĻ¨ā§‡ āĻ•āĻžāĻœ āĻšāĻžāĻ˛āĻžāĻ¨ā§‹ āĻāĻŦāĻ‚ āĻĒāĻ°ā§āĻ¯āĻŦā§‡āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻž (āĻ¯āĻ¤ āĻŦā§‡āĻļāĻŋ āĻ¸ā§‡āĻ˛āĻžāĻ°āĻŋ/āĻ•ā§āĻŦāĻžāĻ°āĻ¨ā§‡āĻŸāĻ¸ āĻāĻŦāĻ‚ āĻ†āĻĒāĻ¨āĻžāĻ° āĻŦāĻŋāĻŦā§‡āĻ• āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ…āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§‡āĻŦā§‡)
  • āĻĄāĻžāĻ¯āĻŧāĻ¨āĻžāĻŽāĻŋāĻ• āĻ“āĻ¯āĻŧāĻžāĻ°ā§āĻ•āĻĢā§āĻ˛ā§‹ āĻœā§‡āĻ¨āĻžāĻ°ā§‡āĻļāĻ¨ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻĒāĻžāĻ‡āĻĨāĻ¨ āĻ•ā§‹āĻĄ āĻ˛āĻŋāĻ–āĻ¤ā§‡ āĻāĻŦāĻ‚ āĻŦā§āĻāĻ¤ā§‡ āĻ–ā§āĻŦ āĻ¸āĻšāĻœ āĻĨā§‡āĻ•ā§‡
  • āĻāĻŦāĻ‚ āĻ°ā§‡āĻĄāĻŋāĻŽā§‡āĻĄ āĻ•āĻŽā§āĻĒā§‹āĻ¨ā§‡āĻ¨ā§āĻŸ āĻāĻŦāĻ‚ āĻ˜āĻ°ā§‡ āĻ¤ā§ˆāĻ°āĻŋ āĻĒā§āĻ˛āĻžāĻ—āĻ‡āĻ¨ āĻ‰āĻ­āĻ¯āĻŧ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻ¯ā§‡āĻ•ā§‹āĻ¨ āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ āĻāĻŦāĻ‚ āĻāĻĒāĻŋāĻ†āĻ‡ āĻāĻ•ā§‡ āĻ…āĻĒāĻ°ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ¸āĻ‚āĻ¯ā§‹āĻ— āĻ•āĻ°āĻžāĻ° āĻ•ā§āĻˇāĻŽāĻ¤āĻž (āĻ¯āĻž āĻ…āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¸āĻšāĻœ)āĨ¤

āĻ†āĻŽāĻ°āĻž āĻāĻ‡ āĻŽāĻ¤ 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

āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ‰āĻ āĻžāĻ° āĻĒāĻ°ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻ“āĻ¯āĻŧā§‡āĻŦ āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻĢā§‡āĻ¸āĻ—ā§āĻ˛āĻŋ āĻĻā§‡āĻ–āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨:

āĻŽā§ŒāĻ˛āĻŋāĻ• āĻ§āĻžāĻ°āĻŖāĻž

āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻāĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ "āĻĄā§āĻ¯āĻžāĻ—āĻ¸" āĻāĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ•āĻŋāĻ›ā§ āĻ¨āĻž āĻŦā§āĻā§‡ āĻĨāĻžāĻ•ā§‡āĻ¨ āĻ¤āĻŦā§‡ āĻāĻ–āĻžāĻ¨ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¸āĻ‚āĻ•ā§āĻˇāĻŋāĻĒā§āĻ¤ āĻ…āĻ­āĻŋāĻ§āĻžāĻ¨ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡:

  • āĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŖāĻ•āĻžāĻ°ā§€ - āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹āĻ¤ā§‡ āĻ¸āĻŦāĻšā§‡āĻ¯āĻŧā§‡ āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻšāĻžāĻšāĻž, āĻ¯āĻŋāĻ¨āĻŋ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻ•āĻ°ā§‡āĻ¨ āĻ¯ā§‡ āĻ°ā§‹āĻŦāĻŸ āĻ•āĻ ā§‹āĻ° āĻĒāĻ°āĻŋāĻļā§āĻ°āĻŽ āĻ•āĻ°ā§‡, āĻāĻ•āĻœāĻ¨ āĻŦā§āĻ¯āĻ•ā§āĻ¤āĻŋ āĻ¨āĻ¯āĻŧ: āĻ¸āĻŽāĻ¯āĻŧāĻ¸ā§‚āĻšā§€ āĻ¨āĻŋāĻ°ā§€āĻ•ā§āĻˇāĻŖ āĻ•āĻ°ā§‡, āĻĄā§‡āĻ— āĻ†āĻĒāĻĄā§‡āĻŸ āĻ•āĻ°ā§‡, āĻ•āĻžāĻœāĻ—ā§āĻ˛āĻŋ āĻšāĻžāĻ˛ā§ āĻ•āĻ°ā§‡āĨ¤

    āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻ­āĻžāĻŦā§‡, āĻĒā§āĻ°āĻžāĻ¨ā§‹ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖāĻ—ā§āĻ˛āĻŋāĻ¤ā§‡, āĻ¤āĻžāĻ° āĻ¸ā§āĻŽā§ƒāĻ¤āĻŋāĻ¤ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ›āĻŋāĻ˛ (āĻ¨āĻž, āĻ…ā§āĻ¯āĻžāĻŽāĻ¨ā§‡āĻ¸āĻŋāĻ¯āĻŧāĻž āĻ¨āĻ¯āĻŧ, āĻ¤āĻŦā§‡ āĻĢāĻžāĻāĻ¸) āĻāĻŦāĻ‚ āĻ˛āĻŋāĻ—ā§āĻ¯āĻžāĻ¸āĻŋ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻŸāĻžāĻ°āĻŸāĻŋ āĻāĻŽāĻ¨āĻ•āĻŋ āĻ•āĻ¨āĻĢāĻŋāĻ—āĻžāĻ°ā§‡ āĻ°āĻ¯āĻŧā§‡ āĻ—ā§‡āĻ›ā§‡ 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 - āĻĒā§āĻ˛āĻžāĻ—āĻ‡āĻ¨ā§‡, āĻāĻ•āĻŸāĻŋ āĻĒāĻžāĻŦāĻ˛āĻŋāĻ• āĻ°āĻŋāĻĒā§‹āĻœāĻŋāĻŸāĻ°āĻŋ āĻ°āĻžāĻ–ā§āĻ¨ āĻāĻŦāĻ‚ āĻ“āĻĒā§‡āĻ¨ āĻ¸ā§‹āĻ°ā§āĻ¸ā§‡ āĻĻāĻŋāĻ¨āĨ¤

āĻ¯āĻ–āĻ¨ āĻ†āĻŽāĻ°āĻž āĻāĻ‡ āĻ¸āĻŦ āĻ…āĻ§ā§āĻ¯āĻ¯āĻŧāĻ¨ āĻ•āĻ°āĻ›āĻŋāĻ˛āĻžāĻŽ, āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ°āĻŋāĻĒā§‹āĻ°ā§āĻŸ āĻ†āĻĒāĻĄā§‡āĻŸ āĻ¸āĻĢāĻ˛āĻ­āĻžāĻŦā§‡ āĻŦā§āĻ¯āĻ°ā§āĻĨ āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ āĻāĻŦāĻ‚ āĻ†āĻŽāĻžāĻ•ā§‡ āĻšā§āĻ¯āĻžāĻ¨ā§‡āĻ˛ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¤ā§āĻ°ā§āĻŸāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒāĻžāĻ āĻžāĻ¤ā§‡ āĻ¸āĻ•ā§āĻˇāĻŽ āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ā§ˇ āĻ†āĻŽāĻŋ āĻāĻŸāĻž āĻ­ā§āĻ˛ āĻ•āĻŋāĻ¨āĻž āĻĻā§‡āĻ–āĻ¤ā§‡ āĻšā§‡āĻ• āĻ•āĻ°āĻ¤ā§‡ āĻ¯āĻžāĻšā§āĻ›āĻŋ...

āĻ…ā§āĻ¯āĻžāĻĒāĻžāĻšāĻŋ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹: āĻ‡āĻŸāĻŋāĻāĻ˛āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ¸āĻšāĻœ āĻ•āĻ°āĻž
āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•ā§āĻ•ā§āĻ°ā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ•āĻŋāĻ›ā§ āĻ­ā§‡āĻ™ā§‡ āĻ—ā§‡āĻ›ā§‡! āĻāĻŸāĻžāĻ‡ āĻ•āĻŋ āĻ†āĻŽāĻ°āĻž āĻ†āĻļāĻž āĻ•āĻ°āĻ›āĻŋāĻ˛āĻžāĻŽ āĻ¨āĻž? āĻšā§āĻŦāĻšā§ !

āĻ†āĻĒāĻ¨āĻŋ āĻĸāĻžāĻ˛āĻž āĻ¯āĻžāĻšā§āĻ›ā§‡āĻ¨?

āĻ¤ā§‹āĻŽāĻžāĻ° āĻ•āĻŋ āĻŽāĻ¨ā§‡ āĻšāĻ¯āĻŧ āĻ†āĻŽāĻŋ āĻ•āĻŋāĻ›ā§ āĻŽāĻŋāĻ¸ āĻ•āĻ°ā§‡āĻ›āĻŋ? āĻŽāĻ¨ā§‡ āĻšāĻšā§āĻ›ā§‡ āĻ¤āĻŋāĻ¨āĻŋ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻĨā§‡āĻ•ā§‡ āĻ­āĻžāĻ°ā§āĻŸāĻŋāĻ•āĻžāĻ¯āĻŧ āĻĄā§‡āĻŸāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻ•āĻ°āĻžāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻļā§āĻ°ā§āĻ¤āĻŋ āĻĻāĻŋāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛ā§‡āĻ¨, āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻĒāĻ°ā§‡ āĻ¤āĻŋāĻ¨āĻŋ āĻ¤āĻž āĻ¨āĻŋāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛ā§‡āĻ¨ āĻāĻŦāĻ‚ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŸāĻŋ āĻĨā§‡āĻ•ā§‡ āĻ¸āĻ°ā§‡ āĻ—āĻŋāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛ā§‡āĻ¨, āĻŦāĻ–āĻžāĻŸā§‡!

āĻāĻ‡ āĻ¨ā§ƒāĻļāĻ‚āĻ¸āĻ¤āĻž āĻ‡āĻšā§āĻ›āĻžāĻ•ā§ƒāĻ¤ āĻ›āĻŋāĻ˛, āĻ†āĻŽāĻžāĻ•ā§‡ āĻ•ā§‡āĻŦāĻ˛ āĻ†āĻĒāĻ¨āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ•āĻŋāĻ›ā§ āĻĒāĻ°āĻŋāĻ­āĻžāĻˇāĻž āĻŦā§‹āĻāĻžāĻ¤ā§‡ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛āĨ¤ āĻāĻ–āĻ¨ āĻ†āĻĒāĻ¨āĻŋ āĻ†āĻ°āĻ“ āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨āĨ¤

āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻž āĻ›āĻŋāĻ˛ āĻāĻ‡:

  1. āĻĻāĻžāĻ— āĻ•āĻ°
  2. āĻ•āĻžāĻœ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°ā§āĻ¨
  3. āĻĻā§‡āĻ–ā§āĻ¨ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ•āĻ¤ āĻ¸ā§āĻ¨ā§āĻĻāĻ°
  4. āĻĒā§‚āĻ°āĻŖ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸ā§‡āĻļāĻ¨ āĻ¨āĻŽā§āĻŦāĻ° āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻ•āĻ°ā§āĻ¨
  5. SQL āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻĨā§‡āĻ•ā§‡ āĻĄā§‡āĻŸāĻž āĻĒāĻžāĻ¨
  6. āĻ­āĻžāĻ°ā§āĻŸāĻŋāĻ•āĻžāĻ¯āĻŧ āĻĄā§‡āĻŸāĻž āĻ°āĻžāĻ–ā§āĻ¨
  7. āĻĒāĻ°āĻŋāĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻ¨ āĻ¸āĻ‚āĻ—ā§āĻ°āĻš āĻ•āĻ°ā§āĻ¨

āĻ¸ā§āĻ¤āĻ°āĻžāĻ‚, āĻāĻ‡ āĻ¸āĻŦ āĻĒā§‡āĻ¤ā§‡ āĻāĻŦāĻ‚ āĻšāĻ˛āĻŽāĻžāĻ¨, āĻ†āĻŽāĻŋ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ›ā§‹āĻŸ āĻ¸āĻ‚āĻ¯ā§‹āĻœāĻ¨ āĻ•āĻ°āĻž 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)
  1. āĻāĻ•āĻŸāĻŋ āĻšā§āĻ•ā§‡āĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§‡ āĻ†āĻŽāĻ°āĻž āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹ āĻĨā§‡āĻ•ā§‡ āĻĒāĻžāĻ‡ pymssql- āĻ¸āĻ‚āĻ¯ā§‹āĻ— āĻ•āĻ°ā§āĻ¨
  2. āĻ†āĻ¸ā§āĻ¨ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡ āĻ¤āĻžāĻ°āĻŋāĻ–ā§‡āĻ° āĻ†āĻ•āĻžāĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¸ā§€āĻŽāĻžāĻŦāĻĻā§āĻ§āĻ¤āĻž āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻ•āĻ°āĻŋ - āĻāĻŸāĻŋ āĻŸā§‡āĻŽāĻĒā§āĻ˛ā§‡āĻŸ āĻ‡āĻžā§āĻœāĻŋāĻ¨ āĻĻā§āĻŦāĻžāĻ°āĻž āĻĢāĻžāĻ‚āĻļāĻ¨ā§‡ āĻ¨āĻŋāĻ•ā§āĻˇā§‡āĻĒ āĻ•āĻ°āĻž āĻšāĻŦā§‡āĨ¤
  3. āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻ–āĻžāĻ“āĻ¯āĻŧāĻžāĻ¨ā§‹ 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)
  1. āĻ†āĻŽāĻ°āĻž āĻāĻ•āĻŸāĻŋ āĻŦāĻŋāĻļā§‡āĻˇ āĻ°āĻŋāĻ¸āĻŋāĻ­āĻžāĻ° āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻ›āĻŋ StringIO.
  2. pandas āĻĻāĻ¯āĻŧāĻž āĻ•āĻ°ā§‡ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•āĻ°āĻž āĻšāĻŦā§‡ DataFrame āĻ†āĻ•āĻžāĻ°ā§‡ CSV-āĻ˛āĻžāĻ‡āĻ¨
  3. āĻ†āĻ¸ā§āĻ¨ āĻāĻ•āĻŸāĻŋ āĻšā§āĻ• āĻĻāĻŋāĻ¯āĻŧā§‡ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻ­āĻžāĻ°ā§āĻŸāĻŋāĻ•āĻžāĻ° āĻ¸āĻžāĻĨā§‡ āĻāĻ•āĻŸāĻŋ āĻ¸āĻ‚āĻ¯ā§‹āĻ— āĻ–ā§āĻ˛āĻŋāĨ¤
  4. āĻāĻŦāĻ‚ āĻāĻ–āĻ¨ āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ 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

āĻ°ā§‡āĻĢāĻžāĻ°ā§‡āĻ¨ā§āĻ¸

āĻāĻŦāĻ‚ āĻ…āĻŦāĻļā§āĻ¯āĻ‡, āĻ—ā§āĻ—āĻ˛ āĻ‡āĻ¸ā§āĻ¯ā§ āĻ•āĻ°āĻžāĻ° āĻĒā§āĻ°āĻĨāĻŽ āĻĻāĻļāĻŸāĻŋ āĻ˛āĻŋāĻ™ā§āĻ• āĻ†āĻŽāĻžāĻ° āĻŦā§āĻ•āĻŽāĻžāĻ°ā§āĻ• āĻĨā§‡āĻ•ā§‡ āĻāĻ¯āĻŧāĻžāĻ°āĻĢā§āĻ˛ā§‹ āĻĢā§‹āĻ˛ā§āĻĄāĻžāĻ°ā§‡āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§āĨ¤

āĻāĻŦāĻ‚ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡ āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻ˛āĻŋāĻ™ā§āĻ•āĻ—ā§āĻ˛āĻŋ:

āĻ‰āĻ¤ā§āĻ¸: www.habr.com