Keeping im Speicher befindlichen Daten synchron mit einer Datei für lange Python-Skript ausgeführt werden

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

Frage

Ich habe eine Python (2.7) Skript, das als Server fungiert, und es wird daher für sehr lange Zeiträume laufen. Dieses Skript hat eine Reihe von Werten, den Überblick zu behalten, von denen jederzeit basierend auf Client-Eingabe ändern kann.

Was ich im Idealfall nach ist etwas, das eine Python-Datenstruktur halten kann (mit Werten von Typen dict, list, unicode, int und float - JSON, im Grunde) in Erinnerung, dass ich es aktualisieren, aber ich will (außer Referenzierung eine der Referenztyp-Instanzen mehr als einmal), während dieser Daten auch up-to-date in einer menschenlesbare Datei zu halten, so dass selbst wenn der Netzstecker gezogen wurde, konnte der Server beginnt gerade nach oben und mit den gleichen Daten fortzusetzen.

Ich weiß, ich bin im Grunde um eine Datenbank zu sprechen, aber die Daten Ich behalte wird sehr einfach und wahrscheinlich weniger als 1 kB die meiste Zeit, so dass ich für die einfachste Lösung freu möglich, das mich zur Verfügung stellen kann mit der beschriebenen Datenintegrität. Gibt es guten Python (2.7) Bibliotheken, die mich so etwas tun lassen?

War es hilfreich?

Lösung

Ich bin damit einverstanden, dass Sie eine voll geblasene Datenbank nicht benötigen, wie es scheint, dass alles, was Sie wollen, ist Atom Datei schreibt . Sie müssen dieses Problem in zwei Teilen, Serialisierung / Deserialisierung, und das Atom Schreiben lösen.

Für den ersten Abschnitt, json oder pickle sind wahrscheinlich geeignete Formate für Sie. JSON hat den Vorteil der menschlichen lesbar ist. Es scheint nicht, als ob dies das primäre Problem, das Sie allerdings gegenüber.

Wenn Sie Ihr Objekt in eine Zeichenfolge serialisiert haben, Verwenden Sie das folgende Verfahren, um eine Datei auf der Festplatte atomar zu schreiben, einen einzigen gleichzeitigen Schriftstellers unter der Annahme, (zumindest auf POSIX, siehe unten):

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)

Während os.rename wird überschrieben ist eine vorhandene Datei und ist atomar auf POSIX, das ist leider nicht der Fall unter Windows. Unter Windows gibt es die Möglichkeit, dass os.unlink gelingen wird, aber os.rename scheitern wird, was bedeutet, dass Sie nur backup_filename haben und keine filename. Wenn Sie Windows-Targeting, müssen Sie diese Möglichkeit prüfen, wenn Sie für die Existenz von filename prüft wird.

Wenn es eine Möglichkeit, mehr als ein gleichzeitigen Schriftsteller ist, werden Sie ein Synchronisierungskonstrukt berücksichtigen müssen.

Andere Tipps

Nun, da Sie wissen, dass wir im Grunde über eine Datenbank zu sprechen, wenn auch ein sehr einfaches, wird man wahrscheinlich nicht überrascht sein, dass ich schlage vor, Sie haben einen Blick auf die sqlite3 Modul.

Gibt es Gründe für den Menschen lesbaren Anforderung?

Ich würde vorschlagen, auf SQLite für eine einfache Datenbank-Lösung suchen oder auf Gurke für eine einfache Art und Weise zu serialise Objekten und schreibe sie auf der Festplatte. Weder ist besonders für Menschen lesbare though.

Weitere Optionen sind JSON oder XML, wie Sie angedeutet - verwenden die in json-Modul gebaut serialisiert werden die Objekte dann, dass die Platte schreiben. Wenn Sie beginnen, überprüfen Sie auf das Vorhandensein der Datei und die Daten laden, falls erforderlich.

Von der docs :

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

Da Sie erwähnen Ihre Daten sind klein, ich würde gehen mit einer einfachen Lösung und verwenden Sie die Gurke Modul, in dem Sie ein python-Objekt in eine Zeile Dump sehr leicht .

Dann gründen Sie nur ein Thema , die in eine Datei Ihr Objekt speichert in definiert Zeitintervalle.

Not a „libraried“ Lösung, aber - wenn ich verstehe Ihre Anforderungen -. Einfach genug für Sie nicht wirklich brauchen eine

EDIT: Sie erwähnten Sie den Fall abdecken wollte, dass ein Problem während des Schreib selbst auftritt, effektiv es eine atomare Transaktion zu machen. In diesem Fall wird die traditionelle Art und Weise zu gehen ist „Log-basierte Wiederherstellung“ verwenden. Es schreibt im Wesentlichen einen Datensatz in eine Protokolldatei sagen, dass „Schreibtransaktion gestartet“ und dann, wenn Sie fertig sind „Schreibtransaktion comitted“ zu schreiben. Wenn ein „gestartet“ hat keine entsprechende „begehen“, dann sind Sie Rollbacks.

In diesem Fall stimme ich zu, dass Sie besser sein könnten mit einer einfachen Datenbank wie SQLite ab. Es könnte ein leichter zu viel des Guten, aber auf der anderen Seite, die Unteilbarkeit der Umsetzung selbst könnte das Rad ein wenig (und ich fand keine offensichtlichen Bibliotheken, die es für Sie tun) werden neu zu erfinden.

Wenn Sie den schlauen Weg zu gehen entscheiden, dieses Thema auf dem Prozeßsynchronisation Kapitel der Silber der Betriebssysteme Buchs behandelt wird, unter dem Abschnitt „atomare Transaktionen“.

Eine sehr einfache (wenn auch vielleicht nicht „transaktions perfekt“) Alternative nur zum Datensatz in eine neue Datei jedes Mal sein würde, so dass, wenn man verdirbt Sie eine Geschichte haben. Sie können sogar eine Prüfsumme für jede Datei automatisch hinzufügen, festzustellen, ob es kaputt ist.

Sie fragen, wie eine Datenbank zu implementieren, die ACID Garantien bietet, aber Sie haben nicht einen guten Grund zur Verfügung gestellt, warum man nicht ein off-the-shelf nutzen können. SQLite ist perfekt für diese Art der Sache und gibt Ihnen diese Garantien.

Allerdings gibt es KirbyBase . Ich habe es nie benutzt, und ich glaube nicht, es ACID Garantien macht, aber es hat einige der Eigenschaften hat Sie suchen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top