Сохранение данных в памяти в синхронизации с файлом для длительного запущенного сценария Python

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

Вопрос

У меня есть сценарий Python (2.7), который действует как сервер, и поэтому он будет работать в течение очень длительных периодов времени. Этот скрипт имеет кучу значений, чтобы отслеживать, что может измениться в любое время на основе клиентского ввода.

Что я в идеале после того, что это то, что может сохранить структуру данных Python (со значениями типов dict, list, unicode, int а также float - JSON, в основном) в памяти, позволяя мне обновить его, однако, как я хочу (кроме ссылки на любой из экземпляров типов ссылки более одного раза), в то время как также хранить эти данные в актуальном состоянии в читаемом файле человека, так что даже если Включение питания была вытащена, сервер может просто запустить и продолжить с теми же данными.

Я знаю, что я в основном говорю о базе данных, но данные, которые я поддерживаю, будет очень простым и, вероятно, менее 1 КБ большую часть времени, поэтому я ищу все возможное решение, которое может предоставить мне описанный целостность данных. Есть ли хорошие библиотеки Python (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. На окнах есть вероятность того, что os.unlink преуспеют, но os.rename потерпит неудачу, что означает, что у вас есть только backup_filename и нет filename. Отказ Если вы нацеливаете Windows, вам нужно будет рассмотреть эту возможность, когда вы проверяете наличие существования filename.

Если есть возможность более чем одного параллельного писателя, вам придется рассмотреть конструкцию синхронизации.

Другие советы

Что ж, так как вы знаете, мы в основном говорим о базе данных, хотя и очень простой, вы, вероятно, не будете удивлены, что предлагаю вам взглянуть на sqlite3. модуль.

Есть причина для читабельного требования человека?

Я бы предложил смотреть на SQLite для простого решения базы данных или на расчету для простых способов серийных объектов и записывать их на диск. Ни один не особенно читается человеком, хотя.

Другие варианты - JSON, или XML, как вы намекаете, - используйте встроенный модуль JSOL для сериализации объектов, а затем напишите это на диск. Когда вы запускаете, проверьте наличие этого файла и загрузите данные, если требуются.

Из документы:

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

Поскольку вы упомянули, что ваши данные маленькие, я бы пошел с простым решением и использовать соленый огурец модуль, который позволяет выбросить объект Python в линию очень легко.

Тогда вы просто настроили Нить Это сохраняет ваш объект в файл в определенных временных интервалах.

Не «библиотекаемое» решение, но - если я понимаю ваши требования - достаточно просто для вас не на самом деле нужен.

Редактировать: Вы упомянули, что вы хотите покрыть случай, когда проблема возникает во время самостоятельной записи, эффективно делая его атомной транзакцией. В этом случае традиционный способ пойти, использует «восстановление на основе журналов». По сути, принципиально написание записи в файл журнала, говоря, что «запись транзакции запущена», а затем запись «запись транзакции Commated», когда вы закончите. Если «начало» не имеет соответствующего «коммита», то вы откатываетесь.

В этом случае я согласен, что вам может быть лучше с простой базой данных, такими как sqlite. Это может быть легкий излишек, но с другой стороны, реализующая атомность самостоятельно может быть немного изобретать колесо (и я не нашел никаких очевидных библиотек, которые делают это для вас).

Если вы решите пройти хитрый путь, эта тема покрыта главами синхронизации процесса Книги операционных систем Сильберсхатца в разделе «Атомные транзакции».

Очень просто (хотя, возможно, не «транзационно Perfect»), альтернатива будет просто записывать в новый файл каждый раз, так что если один коррумпировал у вас история. Вы даже можете добавить контрольную сумму каждому файлу, чтобы автоматически определить, сломано ли он.

Вы спрашиваете, как реализовать базу данных, которая обеспечивает КИСЛОТА Гарантии, но вы не предоставили веской причины, почему вы не можете использовать одну из полки. SQLite идеально подходит для такого рода вещей и дает вам эти гарантии.

Тем не менее, есть Кирбибаза. Отказ Я никогда не использовал его, и я не думаю, что это заставляет кислотные гарантии, но у него есть некоторые характеристики, которые вы ищете.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top