الخطوة 3 في الواجهة الخلفية: إعداد قاعدة البيانات باستخدام SQLAlchemy
ستضيف الآن قاعدة بيانات لتخزين رسائل المحادثة.
ما ستتعلمه
- إعداد SQLAlchemy مع Flask
- تعريف نماذج قاعدة البيانات
- إنشاء الجداول
- إدراج البيانات والاستعلام عنها
الخطوة 1: تحديث init.py لإعداد قاعدة البيانات
عدّل الملف backend/app/__init__.py:
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///chat.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
@app.route("/")
def home():
return jsonify({"message": "Hello Flask!"})
@app.route("/api/status")
def status():
return jsonify({"status": "ok", "version": "1.0"})
with app.app_context():
db.create_all()
return app
if __name__ == "__main__":
app = create_app()
app.run(debug=True, port=5000)
الأسطر الجديدة المهمة:
- db = SQLAlchemy() — ينشئ كائن قاعدة البيانات
- app.config["SQLALCHEMY_DATABASE_URI"] — يخبر Flask باستخدام ملف SQLite اسمه chat.db
- db.init_app(app) — يربط قاعدة البيانات بتطبيق Flask
- db.create_all() — ينشئ الجداول استنادًا إلى نماذجك
الخطوة 2: إنشاء نموذج Message
عدّل الملف backend/app/models.py:
from . import db
from datetime import datetime, timezone
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(1000), nullable=False)
sender = db.Column(db.String(20), nullable=False)
timestamp = db.Column(
db.DateTime, default=lambda: datetime.now(timezone.utc)
)
def to_dict(self):
return {
"id": self.id,
"content": self.content,
"sender": self.sender,
"timestamp": self.timestamp.isoformat()
if self.timestamp
else None,
}
وظيفة كل عمود:
- id — معرف فريد يزداد تلقائيًا
- content — نص الرسالة (حتى 1000 حرف، مطلوب)
- sender — إما "user" أو "ai"، مطلوب
- timestamp — وقت إنشاء الرسالة (القيمة الافتراضية هي الوقت الحالي)
- to_dict() — يحوّل النموذج إلى قاموس لاستخدامه في استجابة JSON
الخطوة 3: استيراد النماذج في init.py
أضف الاستيراد في أعلى __init__.py:
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
from dotenv import load_dotenv
load_dotenv()
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///chat.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
from .models import Message # استورد النماذج بعد تهيئة db
@app.route("/")
def home():
return jsonify({"message": "Hello Flask!"})
@app.route("/api/status")
def status():
return jsonify({"status": "ok", "version": "1.0"})
with app.app_context():
db.create_all()
return app
if __name__ == "__main__":
app = create_app()
app.run(debug=True, port=5000)
الخطوة 4: إضافة اختبار للنموذج
قبل تشغيل الخادم، اكتب اختبارًا يتحقق من أن نموذجك يعمل:
أنشئ الملف backend/tests/test_model.py:
from app.models import Message
def test_create_message(client):
"""A message can be created and read back."""
response = client.post("/api/chat", json={"message": "Hello!"})
assert response.status_code == 200
def test_message_has_required_fields(app):
"""Message model has the right fields."""
with app.app_context():
from app import db
from app.models import Message
msg = Message(content="Test", sender="user")
db.session.add(msg)
db.session.commit()
saved = Message.query.first()
assert saved.content == "Test"
assert saved.sender == "user"
assert saved.id is not None
assert saved.timestamp is not None
شغّله:
cd aiproject/backend
python -m pytest tests/ -v
ينبغي أن ترى كلا الاختبارين ينجحان. الاختبار الثاني ينشئ كائن Message مباشرة دون المرور بنقطة نهاية API — أي أنه يختبر نموذج قاعدة البيانات بمعزل عن بقية التطبيق.
الخطوة 5: التشغيل والتحقق
الخيار أ — بيئة افتراضية:
cd aiproject/backend
source venv/bin/activate
python app/__init__.py
الخيار ب — Docker:
cd aiproject/backend
docker compose up
أوقف الخادم (Ctrl+C) وتحقق من إنشاء الملف instance/chat.db:
البيئة الافتراضية (venv):
ls -la instance/
# → chat.db
Docker: ملف قاعدة البيانات موجود داخل وحدة تخزين Docker (volume). للتحقق من وجوده:
docker compose run app ls -la instance/
# → chat.db
لإعادة ضبط قاعدة البيانات (حذف جميع الرسائل):
docker compose down -v
docker compose up
الخطوة 5: اختبار قاعدة البيانات عبر صدفة Python
cd aiproject/backend
source venv/bin/activate
python3
>>> from app import create_app, db
>>> from app.models import Message
>>> app = create_app()
>>> with app.app_context():
... # أضف رسالة اختبار
... msg = Message(content="Hello database!", sender="user")
... db.session.add(msg)
... db.session.commit()
... print(f"Message ID: {msg.id}")
... # استعلم عن جميع الرسائل
... messages = Message.query.all()
... for m in messages:
... print(m.to_dict())
...
المخرجات المتوقعة:
Message ID: 1
{'id': 1, 'content': 'Hello database!', 'sender': 'user', 'timestamp': '2025-01-15T10:30:00+00:00'}
شرح: ما هو SQLAlchemy؟
SQLAlchemy هو ORM (مخطط الكائنات العلائقية). يتيح لك:
- تعريف جداول قاعدة البيانات على هيئة أصناف Python (
class Message(db.Model)) - التعامل مع الصفوف ككائنات Python (
msg.content) - استخدام دوال Python بدلًا من SQL (
Message.query.all()بدلًا منSELECT * FROM message)
التحقق من عملك
قاعدة بياناتك الآن:
- تحتوي على جدول message بأربعة أعمدة (id, content, sender, timestamp)
- تحتوي على رسالة اختبار واحدة على الأقل
- جاهزة لاستقبال البيانات من نقاط نهاية API