0Pricing
Pandas & NumPy Academy · درس

جدولة عمليات مسار المعالجة وتسجيلها

شغّل مسار المعالجة كبرنامج Python النصي من سطر الأوامر، وسجّل وقتي البدء والانتهاء، واستخدم cron أو مجدولًا للأتمتة.

جدولة عمليات مسار المعالجة وتسجيلها درس مجاني في Pandas & NumPy Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Pandas & NumPy Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

من الدفتر التفاعلي إلى البرنامج النصي

لا يقدم خط أنابيب البيانات الذي يعمل فقط عندما يفتح مطور دفترًا تفاعليًا يدويًا أي قيمة تجارية تتجاوز التشغيل الأول. ولتشغيله تلقائيًا كل يوم، يجب تنظيمه في صورة برنامج نصي بلغة Python يمكن تنفيذه من سطر الأوامر: python pipeline.py. ويتطلب ذلك نقطة دخول if __name__ == '__main__':، وتحليل معلمات سطر الأوامر، وتسجيلًا مناسبًا؛ وهذه هي الركائز الثلاثة للبرنامج النصي الجاهز للإنتاج.

# pipeline.py
import argparse
import logging
import pandas as pd

def main(config_path):
    logging.info(f'Starting pipeline with config: {config_path}')
    # ... run ETL steps ...
    logging.info('Pipeline complete.')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', default='config.json')
    args = parser.parse_args()
    main(args.config)

إعداد تسجيل الأحداث في Python

تُعد الوحدة المدمجة logging في Python الأداة الصحيحة لسجلات خط أنابيب البيانات، وليس عبارات print(). اضبطوا مسجلًا يرسل المخرجات إلى وحدة التحكم وإلى ملف باستخدام logging.basicConfig(). استخدموا المستوى INFO لتسجيل التقدم المعتاد، والمستوى ERROR لتسجيل حالات الفشل. وتبقى السجلات المستندة إلى الملفات بعد انتهاء العملية، وهو أمر ضروري لتصحيح أخطاء عمليات التشغيل المجدولة التي لم يراقبها أحد.

import logging
from datetime import date

log_file = f'pipeline_{date.today()}.log'

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s %(message)s',
    handlers=[
        logging.FileHandler(log_file),
        logging.StreamHandler()
    ]
)

logging.info('Logger configured.')

تسجيل بدء خط أنابيب البيانات وانتهائه

سجّلوا دائمًا وقت بدء تشغيل خط أنابيب البيانات ووقت انتهائه والوقت المنقضي. ينشئ ذلك خط أساس للمقارنة: فإذا كان خط أنابيب البيانات يعمل عادةً خلال 45 ثانية واستغرق اليوم 8 دقائق، فقد حدث تغيير ما؛ ربما أصبح ملف الإدخال أكبر بعشرة أضعاف أو أصبح استعلام قاعدة البيانات بطيئًا. وتجعل إدخالات السجل التي تتضمن وقت البدء والانتهاء هذه المقارنة سهلة مباشرةً من ملف السجل وحده.

import time
import logging

def run_pipeline(config):
    start = time.time()
    logging.info(f'Pipeline START | env={config.get("env", "dev")} | input={config["input_path"]}')

    try:
        df = extract(config)
        df_clean = transform(df, config)
        load(df_clean, config)
        elapsed = time.time() - start
        logging.info(f'Pipeline SUCCESS | rows={len(df_clean)} | elapsed={elapsed:.1f}s')
    except Exception as e:
        logging.error(f'Pipeline FAILED | error={e}', exc_info=True)
        raise

تسجيل أعداد الصفوف لكل خطوة

سجّلوا عدد الصفوف عند دخول كل خطوة تحويل وعند خروجها. يبدو السجل المنظم كما يلي: extract: 50,000 rows → drop_nulls: 49,200 rows → filter: 47,800 rows → output: 47,800 rows. يوضح هذا التتبع فورًا عدد الصفوف التي أُسقطت في كل خطوة وما إذا كانت الأعداد متوقعة. وتظهر الانخفاضات غير المعتادة على هيئة فجوات في الأعداد المسجلة.

def log_step(df, step_name):
    logging.info(f'{step_name}: {len(df):,} rows')
    return df

import pandas as pd

df = (pd.read_csv('orders.csv')
    .pipe(log_step, 'extract')
    .dropna(subset=['revenue'])
    .pipe(log_step, 'drop_nulls')
    .query('quantity > 0')
    .pipe(log_step, 'filter_qty')
)
print('Step logging complete.')

الجدولة باستخدام cron على Linux/Mac

يُعد cron المجدول القياسي في Unix للمهام المتكررة. حرّروا crontab باستخدام crontab -e وأضيفوا سطرًا يحدد وقت تشغيل البرنامج النصي. ويكون التنسيق كما يلي: minute hour day month weekday command. ويستخدم خط أنابيب البيانات الذي يجب تشغيله يوميًا عند الساعة 6:00 صباحًا الأمر 0 6 * * * /usr/bin/python /path/to/pipeline.py. استخدموا دائمًا مسارات مطلقة في إدخالات cron، لأن cron يعمل في بيئة محدودة لا تتضمن إعدادات PATH الخاصة بالصدفة.

# crontab entry — edit with: crontab -e
# Run pipeline.py at 06:00 every day
# 0 6 * * * /opt/homebrew/bin/python /Users/analyst/pipeline.py --config /Users/analyst/config.json >> /Users/analyst/cron.log 2>&1

# Common cron patterns:
# 0 6 * * *      — daily at 06:00
# 0 */4 * * *    — every 4 hours
# 0 9 * * 1      — every Monday at 09:00
print('Cron schedule format: minute hour day month weekday')

الجدولة باستخدام مكتبة Python schedule

توفر مكتبة schedule طريقة مكتوبة بالكامل بلغة Python لتشغيل المهام على فواصل زمنية محددة دون التعامل مع cron. وتفيد في البيئات التي لا يتوفر فيها cron (مثل Windows)، أو عندما ترغبون في وضع منطق الجدولة داخل عملية Python نفسها. غلّفوا خط أنابيب البيانات داخل حلقة مهمة مجدولة، وأبقوا العملية قيد التشغيل لتنفيذ المهمة بشكل متكرر.

# pip install schedule
# import schedule, time

# def job():
#     logging.info('Scheduled run starting...')
#     run_pipeline(CONFIG)

# schedule.every().day.at('06:00').do(job)
# schedule.every(4).hours.do(job)

# while True:
#     schedule.run_pending()
#     time.sleep(60)

print('schedule library: use for in-process Python scheduling')

معالجة الأخطاء ورموز الخروج

يجب أن يعيد البرنامج النصي لخط أنابيب البيانات رمز خروج غير صفري عند فشله، حتى يعرف المجدول أن المهمة فشلت. غلّفوا التنفيذ الرئيسي في كتلة try/except واستدعوا sys.exit(1) عند الفشل. يتحقق كل من cron وJenkins وAirflow من رمز الخروج؛ إذ يؤدي الرمز غير الصفري إلى إطلاق تنبيه أو إعادة تشغيل أو إرسال إشعار. وقد يمر الاستثناء غير المعالج الذي لا يضبط رمز الخروج دون أن تلاحظه أنظمة المراقبة الآلية.

import sys

def main():
    try:
        run_pipeline(CONFIG)
        sys.exit(0)  # success
    except AssertionError as e:
        logging.error(f'Data validation failed: {e}')
        sys.exit(2)  # data error
    except Exception as e:
        logging.error(f'Unexpected error: {e}', exc_info=True)
        sys.exit(1)  # general failure

print('Exit code 0=success, 1=error, 2=data failure')

كتابة ملف ملخص لتشغيل خط أنابيب البيانات

بعد نجاح التشغيل، اكتبوا ملف ملخص صغيرًا بصيغة JSON بجوار المخرجات. أدرجوا وقت التشغيل، وعدد صفوف الإدخال، وعدد صفوف المخرجات، والصفوف التي أُسقطت، والوقت المنقضي. يمكن لأنظمة المراقبة ولوحات المعلومات قراءة هذا الملف لتتبع اتجاهات سلامة خط أنابيب البيانات بمرور الوقت. وتجعل لوحة معلومات تعرض عدد صفوف المخرجات خلال آخر 30 يومًا من السهل تحديد اليوم الذي بدأ فيه مصدر البيانات بتقديم عدد أقل من السجلات.

import json
from datetime import datetime

def write_run_summary(config, input_rows, output_rows, elapsed):
    summary = {
        'run_at': datetime.now().isoformat(),
        'input_path': config['input_path'],
        'input_rows': input_rows,
        'output_rows': output_rows,
        'rows_dropped': input_rows - output_rows,
        'elapsed_seconds': round(elapsed, 2),
        'status': 'success'
    }
    with open('last_run_summary.json', 'w') as f:
        json.dump(summary, f, indent=2)
    print('Run summary written.')

الجدولة القابلة للتكرار: تجنب عمليات التشغيل المزدوجة

إذا شُغّل خط أنابيب البيانات المجدول مرتين عن طريق الخطأ، فيجب ألا يؤدي ذلك إلى إفساد المخرجات. صمّموا خطوة التحميل بحيث تكون قابلة للتكرار بأمان: استخدموا اسم ملف مخرجات يتضمن التاريخ، أو استبدلوا المخرجات نفسها بأحدث نتيجة. وبالنسبة إلى عمليات التحميل إلى قواعد البيانات، استخدموا if_exists='replace' أو نمط UPSERT. لا تستخدموا وضع append مطلقًا دون خطوة لإزالة التكرار، وإلا فستضيف كل عملية تشغيل مجدولة صفوفًا مكررة إلى جدول المخرجات.

from datetime import date

def load_idempotent(df, config):
    # Date-stamped output: each run overwrites its own day's file
    output_path = f"output_{date.today().strftime('%Y%m%d')}.parquet"
    df.to_parquet(output_path, index=False)
    logging.info(f'Loaded {len(df)} rows to {output_path}')

التنبيه عند فشل خط الأنابيب

بالنسبة إلى خطوط الأنابيب التي تعتمد عليها عمليات الأعمال، فإن الصمت بعد حدوث فشل أمر خطير. أعدّ تنبيهًا بسيطًا: إذا لم يُحدَّث ملف ملخص التشغيل خلال الفترة الزمنية المتوقعة، فأرسل رسالة بريد إلكتروني أو رسالة عبر Slack. يمكن لـ Python's smtplib إرسال رسالة بريد إلكتروني عند الفشل، أو يمكنك استخدام webhook للنشر في Slack. أرسل تنبيهًا فورًا عند رمز الخروج 1 أو 2، حتى يعرف المحلل أن التحديث اليومي لم يكتمل قبل أن تلاحظ جهة الأعمال ذلك.

import smtplib

def send_failure_alert(error_msg):
    # Example: send plain-text email via SMTP
    # server = smtplib.SMTP('smtp.example.com', 587)
    # server.sendmail('pipeline@company.com',
    #                 'analyst@company.com',
    #                 f'Subject: Pipeline Failed\n\n{error_msg}')
    # server.quit()
    print(f'[ALERT] Would send failure notification: {error_msg}')

# In main():
# except Exception as e:
#     send_failure_alert(str(e))
#     sys.exit(1)
print('Alert integration pattern shown above.')

استكمال البرنامج النصي لخط الأنابيب المجدول

اجمع كل الأجزاء — تحليل الوسائط، وإعداد التسجيل، وملخص التشغيل، ومعالجة الأخطاء، ورموز الخروج — في برنامج نصي كامل لخط الأنابيب. يمكن وضع هذا البرنامج النصي في أي بيئة، وتوجيهه إلى ملف إعدادات، وجدولته باستخدام cron أو أي منسق لسير العمل. وينتج في كل تنفيذ ملف سجل مؤرخًا، وملخصًا للتشغيل، وملف إخراج مؤرخًا، مما يجعل كل تشغيل قابلًا للتدقيق الكامل وإعادة الإنتاج بشكل مستقل.

# Full script skeleton:
# 1. parse --config argument
# 2. configure logging to file + console
# 3. load JSON config
# 4. validate config
# 5. run extract() -> transform() -> load()
# 6. write run summary JSON
# 7. sys.exit(0) on success, sys.exit(1) on failure

print('Production pipeline script structure complete.')
print('Schedule with: crontab -e  or  python scheduler.py')

اختبار سريع

اختبر مدى فهمك لمفاهيم تحليل البيانات التي تناولها هذا الدرس.

مراجعة الدرس

تعلمت في هذا الدرس: هيكلة خط الأنابيب في صورة برنامج نصي لسطر الأوامر مع تحليل الوسائط والتسجيل، والجدولة باستخدام cron ومعالجة حالات الفشل عبر رموز الخروج غير الصفرية والتنبيهات، وكتابة ملفات ملخص التشغيل وتصميم خطوات تحميل غير متكررة لضمان التنفيذ الآلي الموثوق. تهانينا على إكمال مسار تحليل البيانات: Pandas وNumPy!

الأسئلة الشائعة

هل درس «جدولة عمليات مسار المعالجة وتسجيلها» مجاني؟

نعم — نص درس «جدولة عمليات مسار المعالجة وتسجيلها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Pandas & NumPy Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

ماذا ستتعلم في «جدولة عمليات مسار المعالجة وتسجيلها»؟

شغّل مسار المعالجة كبرنامج Python النصي من سطر الأوامر، وسجّل وقتي البدء والانتهاء، واستخدم cron أو مجدولًا للأتمتة. تتمرن على Pandas & NumPy Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Pandas & NumPy Academy؟

لا تُشترط خبرة سابقة. Pandas & NumPy Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «جدولة عمليات مسار المعالجة وتسجيلها»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Pandas & NumPy Academy هذا؟

نعم. كل درس في Pandas & NumPy Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تنظيم خطوات التحويل في صورة دوال
  2. تخصيص مسارات المعالجة باستخدام قواميس الإعدادات
  3. اختبار خطوات مسار المعالجة بالتأكيدات
  4. جدولة عمليات مسار المعالجة وتسجيلها
← العودة إلى Pandas & NumPy Academy