10  حفظ البيانات واسترجاعها

سَلْسَلة البيانات (Data Serialization) تشير لعملية تحويل البيانات في ذاكرة بايثون (مثل القائمة [] والقاموس {}) من صيغتها الثنائية الخاص باللغة إلى تمثيلٍ ليس خاصًّا بلغةٍ معيَّنة؛ بل يتبع صيغةً متفقًا عليها؛ فإما أن يكون:

  1. تمثيلاً نصيًّا (Plain Text Serialization) متفقًا عليه مثل: xml أو json أو csv ونحوها (وقد تقدَّم عرضُها في باب النص).
  2. أو تمثيلاً ثنائيًّا (Binary Serialization) متفقًا عليه كذلك مثل: pickle أو protobuf أو parquet.

فالتمثيل النصي يتميز بأنه مباشر وواضح بالنسبة للبشر. لكنه أبطأ في المعالجة (سواءً في الكتابة أو في القراءة) وأكبرُ حجمًا في التخزين غالبًا. أما التمثيل الثانئي فهو بعكسه: أقرب للآلة وأصعب في التدقيق عند حدوث الخطأ إلا مع وجود أدوات تساعد في ذلك. لكنه أسرع في المعالجة وأقل حجمًا للتخزين.

وعملية تحويل البيانات المُسَلسَلة (أي المكتوبة بإحدى هذه الصيغ) وقراءَتها في برنامجٍ ما تسمى فك التسلسل (Deserialization). فالتحويل يكون مثلاً من النصي إلى الثنائي في الذاكرة. أو من الثنائي المسلسل إلى الثنائي في الذاكرة.

فالسلسلة وفكها ما هي إلا صياغة لا تغير المكنون بل شكله.

ويختلف شكل البيانات من ثلاثة أوجه:

  1. الصف: [v1, v2, ...]
  2. الربط: {k1: v1, k2: v2, ...}
  3. التضمين: وهو جعل العنصر نفسه صفًّا أو ارتباطًا
    • تضمين الصف لصفوف: [[v1, v2, ...], [v1, v2, ...], ...]
    • تضمين الصف لروابط: [{k1: v1, k2: v2, ...}, {k1: v1, k2: v2, ...}, ...]
    • تضمين الروابط لصفوف: {k1: [v1, v2, ...], k2: [v1, v2, ...], ...}
    • تضمين الروابط لروابط: {k1: {k2: v2, k3: v3, ...}, k2: {k4: v4, k5: v5, ...}, ...}

فالصفوف تتميز بكون كل صفٍّ فيها تدوينًا لمجموعة خصائص تشترك في العمود كله. أما الارتباط ففيه مرونة؛ فمجموعة الارتباطات لا تُلزِم كل ارتباط أن يكون له ذات خصائص الارتباط الذي قبله.

حزمة (csv)

import csv

تسهل حزمة csv المبنية في بايثون التعامل مع البيانات المجدولة المصفصفة.

مثل الملف abc.csv: حيث تفصل الصفوف بسطر \n وتفصل القيَم في السطر بالفاصلة ,. حيث يرمز الاختصار CSV لكلمة Comma Separated Values؛ بمعنى: القيَم المفصول بالفاصلة.

مثالها:

Name,Age,Grade,Done
Adam,22,90,F
Belal,23,92,F
Camal,24,91,T
Dawod,8,99,F
Emad,9,98,F

وكذلك ملف abc.tsv: حيث تفصل الصفوف بسطر \n وتفصل القَم في السطر بالمسافة البادئة \t.

مثالها:

Name    Age    Grade  Done
Adam    22 90  F
Belal   23    92 F
Camal   24    91 T
Dawod   8 99  F
Emad    9  98   F

حفظ جدول البيانات

نفترض أن لدينا قائمة من البيانات على النحو التالي:

rows = [
    ['Adam', 22, 90, 'F'],
    ['Belal', 23, 92, 'F'],
    ['Camal', 24, 91, 'T'],
    ['Dawod', 8, 99, 'F'],
    ['Emad', 9, 98, 'F'],
]
header = ['Name', 'Age', 'Grade', 'Done']
  • حيث تمثل القائمة rows الصفوف
  • وتمثل القائمة header اسم كل عمود

فإن الكتابة تتم بإنشاء الكاتب وتمرير الملف أو مسار الملف إليه (csv.writer(file)) على النحو التالي:

with open('students.csv', mode='w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(header)
    writer.writerows(rows)

ملاحظة، يمكنك محاولة فتح الملف مباشرة من مستكشف الملفات. حاول فتحه باستخدام Excel أو Google Sheet أو أي برنامج جداول بيانات آخر. إذا فتحته باستخدام محرر نصوص، سترى البيانات كملف CSV؛ حرفيًا قيم مفصولة بفواصل.

قراءة جدول البيانات

الآن، دعنا نقرأه كهيكل بيانات في بايثون: كقائمة من القوائم.

data = []
with open('students.csv') as file:
    reader = csv.reader(file)
    for row in reader:
        data.append(row)

وتستطيع كتابة وقراءة الصفوف أيضًا باستعمال:

ملاحظة

غالبًا نستعمل مكتبة بانداس (Pandas) للتعامل مع البيانات الجدولية.

حزمة (json)

import json

تسهل حزمة json المبنية في بايثون التعامل مع البيانات المضمنة.

مثل الملف settings.json:

{
    "theme": "dark",
    "language": "Arabic",
}

أو الملف students.json:

[
    ["Adam", 22, 90, "F"],
    ["Belal", 23, 92, "F"],
    ["Camal", 24, 91, "T"],
    ["Dawod", 8, 99, "F"],
    ["Emad", 9, 98, "F"],
]

لنفترض أن لدينا user_preferences محفوظًا في القاموس التالي، ونريد حفظه في ملف json:

user_preferences = {
    'theme': 'dark',
    'language': 'Arabic',
    'notifications': {
        'email': True,
        'sms': False,
        'push': True
    },
    'last_updated': '2021-09-01',
    'emails': ['example1@domain.com', 'example2@domain.com']
}

كتابة مستند بيانات

لنكتبها في الملف نستعمال json.dump على النحو التالي:

with open('user_preferences.json', mode='w') as file:
    json.dump(user_preferences, file)

قراءة مستند بيانات

فإذا أردنا قراءتها نستعمل json.load على النحو التالي:

with open('user_preferences.json') as file:
    data = json.load(file)
print(data)
{'theme': 'dark', 'language': 'Arabic', 'notifications': {'email': True, 'sms': False, 'push': True}, 'last_updated': '2021-09-01', 'emails': ['example1@domain.com', 'example2@domain.com']}

وانظر:

  • المكتبة المبنية xml لصيغة XML
  • المكتبة الخارجية pyyaml لصيغة YAML