الحفاظ على البيانات في الذاكرة متزامنة مع ملف لنص Python طويل المدى

StackOverflow https://stackoverflow.com/questions/4262403

سؤال

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

ما أنا عليه مثالي هو شيء يمكن أن يحتفظ ببنية بيانات الثعبان (مع قيم الأنواع dict, list, unicode, int و float -JSON ، بشكل أساسي) في الذاكرة ، السماح لي بتحديثه ، كما أريد (باستثناء الرجوع إلى أي من مثيلات النوع المرجعي أكثر من مرة) مع الحفاظ على هذه البيانات أيضًا في ملف قابل للقراءة البشرية ، بحيث إذا كان تم سحب قابس الطاقة ، ويمكن أن يبدأ الخادم ويستمر مع نفس البيانات.

أعلم أنني أتحدث بشكل أساسي عن قاعدة بيانات ، لكن البيانات التي أحتفظ بها ستكون بسيطة للغاية وربما أقل من 1 كيلو بايت في معظم الأوقات ، لذلك أنا أبحث عن أبسط حل يمكن أن يوفر لي الموصوف تكامل البيانات. هل هناك أي مكتبات جيدة للثعبان (2.7) تتيح لي أن أفعل شيئًا كهذا؟

هل كانت مفيدة؟

المحلول

أوافق على أنك لا تحتاج إلى قاعدة بيانات مهب يبدو أن كل ما تريده هو كتاب ذري يكتب. تحتاج إلى حل هذه المشكلة في جزأين ، التسلسل/الهجر ، والكتابة الذرية.

للقسم الأول ، json, ، أو pickle ربما تكون تنسيقات مناسبة لك. تتمتع JSON بميزة كونها قابلة للقراءة البشرية. لا يبدو الأمر كما لو أن هذه المشكلة الأساسية التي تواجهها.

بمجرد قيامك بتسلسل كائنك إلى سلسلة ، استخدم الإجراء التالي لكتابة ملف لقرص ذري ، بافتراض كاتب واحد متزامن (على الأقل على Posix ، انظر أدناه):

import os, platform
backup_filename = "output.back.json"
filename = "output.json"

serialised_str = json.dumps(...)
with open(backup_filename, 'wb') as f:
     f.write(serialised_str)
if platform.system() == 'Windows':
     os.unlink(filename)
os.rename(backup_filename, filename)

في حين os.rename هل سيتم الكتابة فوق ملف موجود وهو ذري على Posix ، وهذا للأسف ليس هو الحال على Windows. على Windows ، هناك احتمال os.unlink سوف تنجح ولكن os.rename سوف تفشل ، وهذا يعني أن لديك فقط backup_filename و لا filename. إذا كنت تستهدف Windows ، فستحتاج إلى النظر في هذا الاحتمال عند التحقق من وجود filename.

إذا كان هناك احتمال لأكثر من كاتب متزامن ، فسيتعين عليك التفكير في بناء المزامنة.

نصائح أخرى

حسنًا ، نظرًا لأنك تعلم أننا نتحدث بشكل أساسي عن قاعدة بيانات ، وإن كانت بسيطة للغاية ، فربما لن تفاجأ بأنني أقترح أن تُلقي نظرة على SQLITE3 وحدة.

أي سبب لمتطلبات القراءة البشرية؟

أود أن أقترح النظر في SQLite لحل قاعدة بيانات بسيط ، أو في Pickle للحصول على طريقة بسيطة لسلسلة الكائنات وكتابتها على القرص. لا يمكن القراءة البشرية بشكل خاص.

الخيارات الأخرى هي JSON ، أو XML كما كنت تلمح إليها - استخدم وحدة JSON المضمنة لتسلسل الكائنات ثم اكتب ذلك إلى القرص. عند البدء ، تحقق من وجود هذا الملف وتحميل البيانات إذا لزم الأمر.

من مستندات:

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}

نظرًا لأنك ذكرت أن بياناتك صغيرة ، سأذهب مع حل بسيط وأستخدم ورطة الوحدة النمطية ، والتي تتيح لك تفريغ كائن بيثون في خط سهل جدا.

ثم قمت فقط بإعداد أ خيط هذا يحفظ كائنك إلى ملف على فترات زمنية محددة.

ليس حل "مكتبة" ، ولكن - إذا فهمت متطلباتك - بسيطة بما يكفي لك ألا تحتاج حقًا إلى واحد.

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

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

إذا قررت الذهاب إلى الطريق ماكر ، يتم تغطية هذا الموضوع في الفصل التزامن من كتاب Silberschatz أنظمة التشغيل ، ضمن قسم "المعاملات الذرية".

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

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

ومع ذلك ، هناك Kirbybase. لم أستخدمها مطلقًا ولا أعتقد أنها تجعل الحمض ضمانات ، ولكن لديها بعض الخصائص التي تبحث عنها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top