نمذجة البيانات باستخدام Pydantic

نمذجة البيانات باستخدام Pydantic

46 دقيقة
١٧ يونيو ٢٠٢٦
المرحلة 1 من 6

مقدمة: ما هي نمذجة البيانات ولماذا Pydantic؟

الدرس الرابع عشر: نمذجة البيانات باستخدام Pydantic

ما هي نمذجة البيانات؟

في عالم البرمجة، عندما نبني تطبيقاً يتعامل مع بيانات (مثل معلومات المستخدمين أو المهام)، نحتاج إلى طريقة منظمة لتمثيل هذه البيانات. نمذجة البيانات هي عملية تحديد شكل وهيكل البيانات التي سيتعامل معها تطبيقك. بدلاً من التعامل مع البيانات كقواميس عشوائية (Dictionaries) كما تعلمنا سابقاً، نقوم بإنشاء "نماذج" (Models) تحدد بدقة ما هي الحقول المطلوبة، ونوع كل حقل، والقيم الافتراضية، والقيود.

لماذا نحتاج Pydantic؟

في الدرس السابق، كنا نستقبل البيانات من المستخدم عبر FastAPI باستخدام معاملات بسيطة. لكن ماذا لو أردنا استقبال كائن كامل (مثل مهمة جديدة تحتوي على عنوان ووصف وتاريخ)؟ هنا يأتي دور Pydantic. Pydantic هي مكتبة بايثون تسمح لنا بتحديد نماذج البيانات بطريقة سهلة وقوية. فوائدها:

  • التحقق التلقائي من صحة البيانات (Validation): تتأكد Pydantic أن البيانات التي تستقبلها تطابق النوع المحدد (مثلاً، تتأكد أن العمر هو رقم صحيح وليس نصاً).
  • تحويل البيانات (Serialization/Deserialization): تحول Pydantic البيانات من صيغة JSON (التي تأتي من طلبات HTTP) إلى كائنات بايثون، والعكس صحيح.
  • توثيق تلقائي: عندما تستخدم Pydantic مع FastAPI، يقوم FastAPI تلقائياً بإنشاء توثيق تفاعلي (Swagger UI) يوضح شكل البيانات المطلوبة.
  • كتابة كود أنظف: بدلاً من كتابة دوال للتحقق من صحة البيانات يدوياً، نعتمد على Pydantic للقيام بذلك.

خطوات التنفيذ: إنشاء أول نموذج بيانات

لنبدأ بتثبيت Pydantic (عادة ما يكون مثبتاً مع FastAPI، لكن للتأكد):

pip install pydantic

الآن، لننشئ ملفاً جديداً باسم models.py في مجلد مشروعنا. سنقوم بتعريف نموذج لمهمة (Task) بسيطة.

مثال كود: نموذج مهمة أساسي

# models.py
from pydantic import BaseModel
from datetime import datetime

class Task(BaseModel):
    title: str
    description: str | None = None  # حقل اختياري، قيمته الافتراضية None
    is_completed: bool = False      # حقل بقيمة افتراضية
    created_at: datetime | None = None # حقل تاريخ اختياري

الشرح:

  • BaseModel: هو الفئة الأساسية التي يجب أن ترث منها جميع نماذج Pydantic.
  • title: str: يعني أن الحقل title يجب أن يكون نصاً (string). هذا حقل إلزامي.
  • description: str | None = None: يعني أن الحقل description يمكن أن يكون نصاً أو قيمة None (أي غير موجود). القيمة الافتراضية هي None، مما يجعله اختيارياً.
  • is_completed: bool = False: حقل منطقي (صح/خطأ) قيمته الافتراضية False.
  • created_at: datetime | None = None: حقل تاريخ ووقت، اختياري.

استخدام النموذج في FastAPI

الآن، لنعدل على ملف main.py الخاص بنا من الدرس السابق لاستخدام هذا النموذج.

# main.py
from fastapi import FastAPI
from models import Task  # استيراد النموذج الذي أنشأناه

app = FastAPI()

# قاعدة بيانات مؤقتة (سنستخدم قاعدة بيانات حقيقية لاحقاً)
tasks_db = []

@app.post("/tasks/")
async def create_task(task: Task):
    # FastAPI ستقوم تلقائياً بتحويل JSON الوارد إلى كائن Task
    # والتحقق من صحة البيانات حسب النموذج
    tasks_db.append(task)
    return {"message": "Task created successfully", "task": task}

@app.get("/tasks/")
async def get_tasks():
    return tasks_db

الشرح:

  • عندما نضيف task: Task كمعامل للدالة create_task، يخبر FastAPI أن البيانات يجب أن تأتي في جسم الطلب (Request Body) وأن تكون مطابقة لنموذج Task.
  • إذا أرسل المستخدم بيانات غير صحيحة (مثلاً، أرسل رقم في حقل title)، سيرد FastAPI تلقائياً برسالة خطأ واضحة توضح المشكلة.
  • جرب تشغيل الخادم (uvicorn main:app --reload) واذهب إلى /docs. ستجد أن Swagger UI أصبح يعرف شكل البيانات المطلوبة ويعرضها لك.
ملاحظة مهمة: في المثال أعلاه، استخدمنا قائمة بسيطة tasks_db لتخزين المهام. هذا ليس حلاً للإنتاج، لكنه ممتاز للتعلم والتجربة. في الدروس القادمة سنستبدلها بقاعدة بيانات حقيقية.

أخطاء شائعة وكيفية تجنبها

  • نسيان استيراد BaseModel: تأكد دائماً من كتابة from pydantic import BaseModel.
  • عدم تحديد نوع الحقل: كل حقل في النموذج يجب أن يكون له نوع (str, int, bool, etc.). إذا لم تحدد النوع، سيعمل الكود لكنه سيفقد ميزة التحقق من الصحة.
  • الخلط بين الحقول الإلزامية والاختيارية: أي حقل ليس له قيمة افتراضية يعتبر إلزامياً. إذا أردت حقل اختيارياً، أعطه قيمة افتراضية مثل None.
  • إرسال بيانات JSON غير صحيحة: عند الاختبار باستخدام curl أو Postman، تأكد من أن مفتاح الحقل في JSON يطابق اسم الحقل في النموذج تماماً (حساس لحالة الأحرف).

تحسين النموذج: إضافة التحقق من صحة البيانات (Validation)

Pydantic تسمح لنا بإضافة قيود أكثر تقدماً على الحقول. على سبيل المثال، لنفرض أننا نريد التأكد من أن عنوان المهمة لا يقل عن 3 أحرف:

# models.py (محدث)
from pydantic import BaseModel, Field
from datetime import datetime

class Task(BaseModel):
    title: str = Field(..., min_length=3, max_length=100, description="عنوان المهمة")
    description: str | None = Field(None, max_length=500)
    is_completed: bool = False
    created_at: datetime | None = None

الشرح:

  • Field(...): النقاط الثلاث ... تعني أن الحقل إلزامي (required).
  • min_length=3: الحد الأدنى لطول النص هو 3 أحرف.
  • max_length=100: الحد الأقصى هو 100 حرف.
  • إذا حاول المستخدم إرسال عنوان بطرفين فقط، سيرفضه Pydantic تلقائياً مع رسالة خطأ.
نصيحة عملية: استخدم Field لتوثيق نموذجك بشكل أفضل. إضافة description تجعل توثيق Swagger UI أكثر وضوحاً للمطورين الآخرين (أو لنفسك في المستقبل).

تمرين صغير

الآن حان دورك للتطبيق!

  1. أنشئ نموذجاً جديداً باسم User في ملف models.py يحتوي على الحقول التالية:
    • username: نص، إلزامي، بطول لا يقل عن 3 ولا يزيد عن 20 حرفاً.
    • email: نص، إلزامي. (تلميح: يمكنك استخدام EmailStr من Pydantic للتحقق من صحة البريد الإلكتروني، لكن للتبسيط استخدم str).
    • age: عدد صحيح (int)، اختياري، بقيمة افتراضية None.
  2. أضف نقطة نهاية (endpoint) جديدة في main.py:
    • المسار: /users/
    • طريقة الطلب: POST
    • تستقبل كائن User وتعيده مع رسالة ترحيبية.
  3. اختبر نقطة النهاية الجديدة باستخدام Swagger UI (/docs) أو باستخدام curl.

بعد الانتهاء من التمرين، ستكون قد فهمت تماماً كيفية إنشاء نماذج بيانات قوية وآمنة باستخدام Pydantic، مما يضع أساساً متيناً لبناء API متكامل في الدروس القادمة.

جاري تحميل التقييمات...