البرمجة

استخدام SQLite مع فلاسک

جدول المحتوى

استخدام قاعدة بيانات SQLite في تطبيق فلاسـك Flask: دليل شامل ومتعمق

تُعتبر قواعد البيانات جزءًا أساسيًا من تطوير التطبيقات الحديثة، ولا سيما تطبيقات الويب التي تعتمد على تخزين واسترجاع البيانات بكفاءة وسلاسة. من بين قواعد البيانات الخفيفة والشائعة الاستخدام، تأتي قاعدة بيانات SQLite كخيار مفضل للمشاريع الصغيرة والمتوسطة، وأحيانًا حتى الكبيرة، نظرًا لسهولة استخدامها، وعدم حاجتها لخادم قاعدة بيانات منفصل، بالإضافة إلى تكاملها الممتاز مع لغة البرمجة بايثون وإطار العمل Flask. في هذا المقال سيتم استعراض كيفية استخدام قاعدة بيانات SQLite مع فلاسـك بشكل تفصيلي، مع شرح المفاهيم الأساسية، الخطوات العملية، وأفضل الممارسات، لتطوير تطبيق ويب فعال ومرن.


مقدمة عن SQLite و Flask

ما هي SQLite؟

SQLite هي قاعدة بيانات علائقية مدمجة (Embedded Relational Database)، تتميز بصغر حجمها وبكونها لا تعتمد على وجود خادم خارجي (Serverless)، إذ تُخزن البيانات في ملف واحد فقط على القرص الصلب. تم تصميم SQLite لتوفير حل بسيط وفعال لتخزين البيانات، مع ضمان أداء جيد، ودعم كامل للمعاملات (Transactions) ومعايير SQL القياسية.

بسبب بساطتها وسهولة استخدامها، تُستخدم SQLite بكثرة في تطبيقات الهواتف الذكية، تطبيقات سطح المكتب، وكذلك في بيئات التطوير والاختبار لتطبيقات الويب.

ما هو Flask؟

فلاسـك (Flask) هو إطار عمل ويب خفيف الوزن مبني على لغة البرمجة بايثون، يُستخدم لإنشاء تطبيقات ويب متنوعة تبدأ من المشاريع البسيطة وحتى المعقدة. يتميز Flask بمرونته العالية، وبساطة واجهته، وعدم وجود قواعد صارمة تُلزم المطور بطريقة معينة لبناء التطبيق، ما يجعله مثاليًا للمشاريع التي تتطلب سرعة التطوير وحرية اختيار الأدوات والمكتبات.


لماذا اختيار SQLite مع Flask؟

  • سهولة التثبيت والاستخدام: SQLite لا تتطلب إعداد خادم قاعدة بيانات منفصل، فهي مجرد ملف تُخزن فيه البيانات. هذا يقلل من تعقيدات الإعداد في بيئة التطوير أو في المشاريع الصغيرة.

  • تكامل سلس مع بايثون: نظرًا لأن SQLite مدمجة في مكتبة sqlite3 القياسية في بايثون، يمكن للمطورين البدء فورًا دون الحاجة لتثبيت مكتبات خارجية.

  • أداء جيد مع البيانات الصغيرة والمتوسطة: عند التعامل مع تطبيقات ذات حجم بيانات محدود وعدد مستخدمين متوسط، تقدم SQLite أداء عاليًا جدًا.

  • صغر الحجم وعدم الحاجة للصيانة المعقدة: كونها لا تعتمد على سيرفر منفصل يجعلها مثالية للتطبيقات التي تحتاج إلى بساطة في النشر والإدارة.


مكونات الربط بين Flask و SQLite

لدمج SQLite مع Flask، تحتاج إلى التعامل مع:

  1. إنشاء قاعدة البيانات والاتصال بها: حيث يمكن لقاعدة البيانات SQLite أن تُنشأ تلقائيًا عند أول اتصال.

  2. تنفيذ استعلامات SQL: لإدخال واسترجاع وتحديث البيانات.

  3. إدارة جلسات العمل (Sessions) وإغلاق الاتصال: لتفادي تسرب الموارد وضمان الأداء.

  4. استخدام مكتبات إضافية تسهل التعامل مع قواعد البيانات: مثل SQLAlchemy أو Flask-SQLAlchemy.


إعداد بيئة العمل

لبدء مشروع Flask يستخدم SQLite، يجب التأكد من وجود:

  • لغة بايثون مثبتة (يفضل الإصدار 3.7 فما فوق).

  • مكتبة Flask.

  • مكتبة SQLite مدمجة مع بايثون (موجودة بشكل افتراضي).

يمكن تثبيت Flask عبر:

bash
pip install Flask

وفي حال استخدام مكتبة Flask-SQLAlchemy التي تسهل التعامل مع قواعد البيانات العلائقية، يمكن تثبيتها عبر:

bash
pip install Flask-SQLAlchemy

إنشاء مشروع Flask مع SQLite خطوة بخطوة

1. إعداد هيكل المشروع الأساسي

ابدأ بإنشاء مجلد المشروع، ثم ملف التطبيق app.py، ومجلد خاص بالقوالب (templates) والمجلدات الأخرى حسب الحاجة.

2. الاتصال بقاعدة البيانات SQLite

في أبسط صورة، يمكن الاتصال بقاعدة البيانات عبر مكتبة sqlite3 المدمجة في بايثون:

python
import sqlite3 from flask import Flask, g app = Flask(__name__) DATABASE = 'database.db' def get_db(): db = getattr(g, '_database', None) if db is None: db = g._database = sqlite3.connect(DATABASE) return db @app.teardown_appcontext def close_connection(exception): db = getattr(g, '_database', None) if db is not None: db.close()

في الكود أعلاه:

  • get_db() تضمن وجود اتصال واحد بقاعدة البيانات لكل طلب ويب.

  • close_connection تغلق الاتصال تلقائيًا بعد الانتهاء من الطلب.

3. إنشاء جدول في قاعدة البيانات

يمكن استخدام استعلام SQL لإنشاء جدول المستخدمين (مثلاً) إذا لم يكن موجودًا:

python
def init_db(): with app.app_context(): db = get_db() cursor = db.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, email TEXT NOT NULL UNIQUE ) ''') db.commit()

يُنصح باستدعاء init_db() مرة واحدة عند إعداد المشروع.

4. تنفيذ عمليات CRUD (إنشاء، قراءة، تحديث، حذف)

إضافة مستخدم جديد:

python
def add_user(username, email): db = get_db() cursor = db.cursor() cursor.execute('INSERT INTO users (username, email) VALUES (?, ?)', (username, email)) db.commit()

استرجاع المستخدمين:

python
def get_users(): db = get_db() cursor = db.cursor() cursor.execute('SELECT id, username, email FROM users') return cursor.fetchall()

تحديث بيانات مستخدم:

python
def update_user(user_id, new_email): db = get_db() cursor = db.cursor() cursor.execute('UPDATE users SET email = ? WHERE id = ?', (new_email, user_id)) db.commit()

حذف مستخدم:

python
def delete_user(user_id): db = get_db() cursor = db.cursor() cursor.execute('DELETE FROM users WHERE id = ?', (user_id,)) db.commit()

استخدام Flask-SQLAlchemy مع SQLite: تبسيط التعامل

مكتبة Flask-SQLAlchemy هي امتداد لـ SQLAlchemy مصمم خصيصًا لتكامل سلس مع Flask، ويوفر طبقة تجريدية تساعد في إدارة قواعد البيانات عن طريق ORM (Object Relational Mapping)، ما يسمح بالتعامل مع قواعد البيانات ككائنات ببرمجة كائنية (OOP).

إعداد المشروع مع Flask-SQLAlchemy

python
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db' # استخدام SQLite app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app)

إنشاء نموذج بيانات (Model)

python
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) def __repr__(self): return f'{self.username}>'

إنشاء قاعدة البيانات والجداول

python
with app.app_context(): db.create_all()

عمليات CRUD باستخدام ORM

إضافة مستخدم:

python
def add_user(username, email): new_user = User(username=username, email=email) db.session.add(new_user) db.session.commit()

استرجاع المستخدمين:

python
def get_users(): return User.query.all()

تحديث المستخدم:

python
def update_user(user_id, new_email): user = User.query.get(user_id) if user: user.email = new_email db.session.commit()

حذف المستخدم:

python
def delete_user(user_id): user = User.query.get(user_id) if user: db.session.delete(user) db.session.commit()

التعامل مع ترابط الطلبات (Request Context) وإدارة الاتصالات

في Flask، يُعتبر التعامل مع قواعد البيانات ضمن نطاق الطلب Request Context من الأمور المهمة لتفادي المشكلات الناتجة عن اتصالات متكررة أو تسربها.

  • استخدام g في Flask لتخزين الاتصال الحالي بقاعدة البيانات يجعل من السهل إعادة استخدامه خلال معالجة الطلب الواحد.

  • يجب دائمًا إغلاق الاتصال بعد الانتهاء، ما يساعد في تحرير الموارد.


إدارة المهاجرات (Migrations) في مشاريع Flask مع SQLite

عند تطوير تطبيقات قابلة للنمو، قد يتغير هيكل قاعدة البيانات، ما يتطلب ترحيل هذه التغييرات بدون فقدان البيانات.

يتم ذلك عادة باستخدام مكتبة Flask-Migrate التي تعتمد على Alembic.

تثبيت Flask-Migrate

bash
pip install Flask-Migrate

إعداد Flask-Migrate في المشروع

python
from flask_migrate import Migrate migrate = Migrate(app, db)

استخدام الأوامر في الطرفية

  • تهيئة المهاجرات:

bash
flask db init
  • إنشاء نسخة ترحيل بناءً على التغييرات:

bash
flask db migrate -m "Initial migration."
  • تطبيق التغييرات على قاعدة البيانات:

bash
flask db upgrade

اعتبارات الأداء عند استخدام SQLite مع Flask

  • SQLite مثالية لتطبيقات ذات استخدام محدود للكتابة، حيث أن الكتابة في SQLite تُجرى باستخدام قفل كامل على الملف.

  • عند وجود تطبيقات تتطلب عددًا كبيرًا من العمليات المتزامنة أو حجم بيانات كبير، يُفضل الانتقال إلى قواعد بيانات أكثر تطورًا مثل PostgreSQL أو MySQL.

  • يمكن تحسين الأداء من خلال ضبط بعض الخيارات مثل تمكين التخزين المؤقت (PRAGMA cache_size)، أو ضبط وضع الكتابة (WAL - Write-Ahead Logging).


تأمين تطبيق Flask مع SQLite

  • التحقق من صحة البيانات المدخلة: لتجنب هجمات حقن SQL (SQL Injection)، يجب دائمًا استخدام المعاملات المتغيرة (? أو Named parameters) وعدم بناء الاستعلامات باستخدام التنسيق النصي المباشر.

  • إدارة الصلاحيات والبيانات الحساسة: يجب تشفير أو حماية المعلومات الحساسة مثل كلمات المرور باستخدام تقنيات التشفير المناسبة (مثل bcrypt أو werkzeug.security في بايثون).

  • تأمين ملف قاعدة البيانات: تأكد من أن ملف قاعدة البيانات مخزن في مسار آمن ولا يمكن الوصول إليه عبر الشبكة أو من قبل مستخدمين غير مخولين.


مثال تطبيقي كامل باستخدام Flask و SQLite

فيما يلي مثال عملي يربط كل المفاهيم السابقة:

python
from flask import Flask, request, jsonify, g import sqlite3 app = Flask(__name__) DATABASE = 'database.db' def get_db(): db = getattr(g, '_database', None) if db is None: db = g._database = sqlite3.connect(DATABASE) db.row_factory = sqlite3.Row return db @app.teardown_appcontext def close_connection(exception): db = getattr(g, '_database', None) if db is not None: db.close() def init_db(): with app.app_context(): db = get_db() db.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, email TEXT NOT NULL UNIQUE ) ''') db.commit() @app.route('/users', methods=['GET']) def list_users(): db = get_db() users = db.execute('SELECT * FROM users').fetchall() return jsonify([dict(user) for user in users]) @app.route('/users', methods=['POST']) def create_user(): data = request.get_json() username = data.get('username') email = data.get('email') if not username or not email: return jsonify({'error': 'Missing username or email'}), 400 db = get_db() try: db.execute('INSERT INTO users (username, email) VALUES (?, ?)', (username, email)) db.commit() return jsonify({'message': 'User created successfully'}), 201 except sqlite3.IntegrityError: return jsonify({'error': 'Email must be unique'}), 409 if __name__ == '__main__': init_db() app.run(debug=True)

خلاصة

تُعتبر قاعدة بيانات SQLite خيارًا ممتازًا لتطبيقات Flask التي تتطلب بساطة وسرعة في إعداد قاعدة البيانات مع أداء جيد للبيانات الصغيرة والمتوسطة.

الاعتماد على SQLite يقلل من تعقيد البنية التحتية، ويتيح بدء تطوير التطبيقات بسرعة، مع إمكانيات كبيرة بفضل دعم SQL الكامل.

بجانب استخدام مكتبة sqlite3 القياسية، يمكن الاستفادة من Flask-SQLAlchemy لتسهيل البرمجة وتحويل العمليات إلى نماذج كائنية، مما يحسن جودة وأمان الكود.

الاهتمام بإدارة الاتصالات بشكل صحيح، حماية البيانات، ومراعاة حجم وعدد المستخدمين، كلها عوامل تحدد نجاح استخدام SQLite في بيئة Flask.


المصادر والمراجع

  1. SQLite Official Documentation

  2. Flask Official Documentation

  3. Flask-SQLAlchemy Documentation

  4. Flask-Migrate Documentation


بهذا الشرح التفصيلي يمكن للمطورين بناء تطبيقات ويب متكاملة تعتمد على Flask وقاعدة بيانات SQLite، مع فهم معمق لأساسيات قواعد البيانات، طرق التفاعل مع SQLite، وكيفية إدارة المشروع بشكل احترافي.