البرمجة

التعامل مع SQLite في Flask

التعامل مع قواعد البيانات SQLite في تطبيقات Flask

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

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


لمحة عامة عن SQLite

تعتبر SQLite قاعدة بيانات علائقية Relational Database مدمجة وخفيفة الحجم، ولا تعتمد على نموذج العميل/الخادم كما هو الحال في قواعد البيانات مثل MySQL أو PostgreSQL. يتم تخزين قاعدة البيانات في ملف واحد على القرص، مما يجعل عملية نشر وصيانة التطبيق أكثر بساطة. تتميز SQLite بما يلي:

  • لا تحتاج إلى خادم قواعد بيانات منفصل.

  • ملف قاعدة البيانات هو ملف واحد يمكن نقله أو نسخه بسهولة.

  • أداء مرتفع للتطبيقات الصغيرة والمتوسطة.

  • دعم متكامل في لغة Python من خلال مكتبة sqlite3 القياسية.


مقدمة إلى Flask

Flask هو إطار عمل خفيف لبناء تطبيقات الويب باستخدام Python. يتميز بالمرونة والبساطة، ويعتمد على فلسفة “microframework”، أي أنه لا يفرض الكثير من الأدوات أو المكونات على المطور، مما يمنحه الحرية في اختيار المكتبات المناسبة.

من خلال Flask يمكن بسهولة إعداد بنية RESTful للتطبيق، وتعريف المسارات، والتعامل مع النماذج، وتكامل قاعدة البيانات.


إنشاء مشروع Flask متكامل مع SQLite

الهيكل الأساسي للمشروع

يتبع مشروع Flask عادة الهيكل التالي:

pgsql
myapp/ │ ├── app.py ├── schema.sql ├── templates/ │ └── index.html ├── static/ │ └── style.css └── instance/ └── mydb.sqlite

إنشاء تطبيق Flask

python
from flask import Flask, g import sqlite3 import os app = Flask(__name__) app.config['DATABASE'] = os.path.join(app.instance_path, 'mydb.sqlite') try: os.makedirs(app.instance_path) except OSError: pass

في هذا الجزء يتم تهيئة التطبيق وتعريف مسار قاعدة البيانات ضمن مجلد instance الذي يُستخدم لحفظ ملفات لا يجب رفعها إلى Git مثل قواعد البيانات ومفاتيح التشفير.


الاتصال بقاعدة البيانات

للتعامل مع قاعدة البيانات بشكل صحيح داخل Flask، يتم استخدام طريقة تعتمد على التعامل السياقي context management، مع الاستفادة من g لتخزين الاتصال بقاعدة البيانات لكل طلب.

python
def get_db(): if 'db' not in g: g.db = sqlite3.connect( app.config['DATABASE'], detect_types=sqlite3.PARSE_DECLTYPES ) g.db.row_factory = sqlite3.Row return g.db @app.teardown_appcontext def close_db(error): db = g.pop('db', None) if db is not None: db.close()
  • get_db() تنشئ الاتصال بقاعدة البيانات وتعيده.

  • close_db() يتم تنفيذها تلقائيًا بعد نهاية كل طلب لإغلاق الاتصال بالقاعدة.


إنشاء الجداول باستخدام SQL

يتم إنشاء الجداول من خلال ملف SQL مستقل لتسهيل تنظيم الكود. على سبيل المثال:

schema.sql

sql
DROP TABLE IF EXISTS users; CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password TEXT NOT NULL );

يتم تنفيذ هذا الملف من خلال سكربت داخل Flask:

python
def init_db(): db = get_db() with open('schema.sql', 'r') as f: db.executescript(f.read())

ولتنفيذ هذا الأمر يدويًا:

python
@app.cli.command('init-db') def init_db_command(): init_db() print('Initialized the database.')

تنفيذ العمليات على قاعدة البيانات

إدخال البيانات

python
def insert_user(username, password): db = get_db() db.execute( 'INSERT INTO users (username, password) VALUES (?, ?)', (username, password) ) db.commit()

استرجاع البيانات

python
def get_user(username): db = get_db() user = db.execute( 'SELECT * FROM users WHERE username = ?', (username,) ).fetchone() return user

تحديث البيانات

python
def update_password(username, new_password): db = get_db() db.execute( 'UPDATE users SET password = ? WHERE username = ?', (new_password, username) ) db.commit()

حذف البيانات

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

دمج قاعدة البيانات مع الواجهات والنماذج

عند بناء واجهات تفاعلية، يتم غالبًا استخدام مكتبة Flask-WTF لتبسيط التعامل مع النماذج. وفي هذه الحالة، يمكن استخدام البيانات المخزنة في SQLite لتوليد أو معالجة استجابات المستخدم.

مثال على واجهة تسجيل مستخدم:

python
from flask import render_template, request, redirect, url_for, flash @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] if get_user(username): flash('اسم المستخدم موجود مسبقاً.') else: insert_user(username, password) flash('تم التسجيل بنجاح.') return redirect(url_for('login')) return render_template('register.html')

التعامل مع الجلسات وحماية البيانات

عند استخدام SQLite لتخزين معلومات حساسة مثل كلمات المرور، من الضروري تشفير هذه البيانات قبل حفظها في القاعدة. يمكن استخدام مكتبة werkzeug.security لهذا الغرض.

python
from werkzeug.security import generate_password_hash, check_password_hash hashed_password = generate_password_hash(password)

وعند التحقق:

python
check_password_hash(hashed_password, input_password)

أفضل الممارسات في استخدام SQLite مع Flask

الممارسة التوصية
تنظيم الكود فصل التعامل مع قاعدة البيانات في ملفات مستقلة
حماية البيانات تشفير كلمات المرور وعدم تخزين معلومات حساسة بشكل نص صريح
الأداء استخدام row_factory للحصول على بيانات كـ dict
إدارة الاتصال فتح الاتصال في بداية الطلب وإغلاقه بنهايته
التهيئة استخدام أمر flask init-db لتهيئة القاعدة تلقائيًا

تكامل Flask-SQLAlchemy (اختياري)

رغم أن sqlite3 تكفي في العديد من المشاريع، إلا أن استخدام SQLAlchemy، وهو ORM قوي، يساعد في تنظيم البيانات والتعامل معها ككائنات.

bash
pip install flask-sqlalchemy
python
from flask_sqlalchemy import SQLAlchemy app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydb.sqlite' db = SQLAlchemy(app) class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password = db.Column(db.String(120), nullable=False)

بعد ذلك، يتم تنفيذ:

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

حالات استخدام واقعية

تستخدم SQLite مع Flask في عدد من السيناريوهات، منها:

  • أنظمة إدارة محتوى بسيطة.

  • نماذج أولية لتطبيقات أكبر قبل استخدام PostgreSQL أو MySQL.

  • تطبيقات سطح المكتب المعتمدة على Flask مثل أدوات إدارة.

  • أنظمة إدارة مهام صغيرة مخصصة لفريق محدد.


التحديات والقيود

رغم المزايا العديدة لـ SQLite، إلا أن هناك بعض التحديات التي يجب أخذها بعين الاعتبار:

  • لا يدعم التزامن العالي بين عدد كبير من المستخدمين.

  • الأداء قد يتأثر في حالة وجود ملايين الصفوف.

  • لا يدعم بعض الميزات المتقدمة المتوفرة في أنظمة مثل PostgreSQL أو Oracle.


الخلاصة

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


المراجع:

  1. Flask Documentation

  2. SQLite Documentation