تحتاج ترحيل قاعدة SQLite باستخدام Python عندما تغيّر بنية جدول موجود في تطبيق فعلي. نجاح أمر ALTER TABLE وحده لا يضمن سلامة البيانات؛ لذلك اجمع بين النسخة الاحتياطية والمعاملة والتحقق من النتائج وخطة استرجاع مجربة.
قبل ترحيل قاعدة SQLite باستخدام Python
اعمل على نسخة تجريبية من قاعدة البيانات، ثم أوقف عمليات الكتابة أثناء التحديث الإنتاجي. احتفظ بنسخة احتياطية متسقة باستخدام SQLite Backup API، لا بنسخ الملف عشوائيًا أثناء الكتابة. وتأكد من إصدار SQLite الفعلي الذي تستخدمه مكتبة Python.
مثال إضافة عمود اختياري بطريقة آمنة
import sqlite3
from pathlib import Path
from contextlib import closing
from datetime import datetime, timezone
path = Path('app.db')
if not path.is_file():
raise FileNotFoundError('app.db not found')
backup_path = Path(f'app-{datetime.now(timezone.utc):%Y%m%d-%H%M%S-%f}.backup.db')
with closing(sqlite3.connect(path)) as source:
with closing(sqlite3.connect(backup_path)) as backup:
source.backup(backup)
with closing(sqlite3.connect(path)) as db:
try:
db.execute('BEGIN IMMEDIATE')
old_count = db.execute('SELECT COUNT(*) FROM customers').fetchone()[0]
cols = {row[1] for row in db.execute('PRAGMA table_info(customers)')}
if 'phone' not in cols:
db.execute('ALTER TABLE customers ADD COLUMN phone TEXT')
new_count = db.execute('SELECT COUNT(*) FROM customers').fetchone()[0]
if old_count != new_count:
raise RuntimeError('Row count changed')
if db.execute('PRAGMA integrity_check').fetchone()[0] != 'ok':
raise RuntimeError('Integrity check failed')
if db.execute('PRAGMA foreign_key_check').fetchall():
raise RuntimeError('Foreign-key check failed')
db.commit()
except Exception:
db.rollback()
raise
print('Migration completed; backup:', backup_path)
يفترض المثال وجود جدول customers؛ استبدله بجدول مشروعك. ينشئ ملف نسخة احتياطية مستقلًا في كل تشغيل باستخدام توقيت UTC، ثم يضيف العمود phone إن لم يكن موجودًا. قبل الالتزام بالمعاملة، يقارن عدد الصفوف ويفحص سلامة قاعدة البيانات والعلاقات المرجعية. وقد تختلف طريقة الترحيل عند إعادة بناء جدول أو تغيير قيد موجود.
كيفية التحقق من البيانات قبل الترحيل وبعده
- أنشئ قاعدة تجريبية فيها جدول customers وسجلات معروفة، ثم احسب الصفوف وسجّل نسخة من المفاتيح الأساسية.
- احفظ الكود باسم migrate.py في مجلد قاعدة app.db، وشغّله باستخدام python migrate.py. لا تشغّله على قاعدة إنتاجية قبل اختبار استعادة النسخة الاحتياطية.
- تحقق من اسم ملف النسخة الاحتياطية، ومن وجود العمود phone وبقاء السجلات كما هي، وشغّل PRAGMA integrity_check و PRAGMA foreign_key_check.
- شغّل البرنامج ثانيةً على نسخة تجريبية للتحقق من عدم محاولة إضافة العمود نفسه، ثم شغّل اختبارات التطبيق التي تستخدم البنية الجديدة.
- إذا فشلت اختبارات التطبيق بعد الترحيل، أوقف الكتابة أولًا ثم قيّم الاستعادة والبيانات الأحدث من تاريخ النسخة الاحتياطية.
ماذا لو أردت تعديل قيود العمود أو نوعه
لا يدعم ALTER TABLE في SQLite كل تغييرات البنية مباشرة. قد تحتاج إلى بناء جدول جديد ثم نقل البيانات وإعادة إنشاء الفهارس والمحفزات والعروض، مع التحقق من القيود. اقرأ الإجراء الرسمي كاملًا قبل النقل؛ فتعطيل المفاتيح الأجنبية أو إسقاط جدول دون خطة قد يسبب خسائر.
كيف تتراجع عن ترحيل فاشل
إذا وقع الخطأ داخل معاملة لم تلتزم بها بعد، نفّذ rollback. أما إذا التزمت بالترحيل ثم اكتشفت خللًا، فلا تفترض أن التراجع عن المخطط وحده يعيد كل البيانات؛ أوقف الكتابة واسترجع النسخة السليمة بعد حساب البيانات التي ظهرت منذ أخذها.
احتفظ بسجل إصدار للمخطط ونسخة احتياطية قابلة للاستعادة، واجعل كل ترحيل محددًا وقابلًا للتكرار متى أمكن. بهذه الطريقة تصبح تغييرات قاعدة البيانات خطوة منضبطة بدل تعديل مباشر غير قابل للتراجع.
التعليقات 0
شارك رأيك أو أضف معلومة مفيدة إلى النقاش.
لا توجد تعليقات بعد. يمكنك بدء النقاش.