我有一个Python(2.7)脚本充当服务器,因此它会运行很长一段时间。该脚本有一堆值,可以根据客户端输入随时跟踪哪些值可以更改。
理想情况下,我可以保留Python数据结构(值类型为dict
,list
,unicode
,int
和{ {1}} - JSON,基本上)在内存中,让我更新它但我想要(除了多次引用任何引用类型实例),同时还将这些数据保持在人类可读的文件中,所以即使拔掉电源插头,服务器也可以启动并继续使用相同的数据。
我知道我基本上都在谈论数据库,但我保留的数据非常简单,大部分时间可能都不到1 kB,所以我正在寻找最简单的数据库。可能的解决方案可以为我提供所描述的数据完整性。有没有好的Python(2.7)库可以让我做这样的事情?
答案 0 :(得分:4)
好吧,既然你知道我们基本上是在谈论一个数据库,虽然这个数据库非常简单,但我建议你看一下sqlite3模块,你可能不会感到惊讶。
答案 1 :(得分:2)
人类可读要求的任何原因?
我建议在sqlite中查找简单的数据库解决方案,或者在pickle中查找序列化对象并将其写入磁盘的简单方法。但两者都不是特别易读的。
其他选项是您所暗示的JSON或XML - 使用内置的json模块序列化对象,然后将其写入磁盘。启动时,检查是否存在该文件,并在需要时加载数据。
来自docs:
>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
"4": 5,
"6": 7
}
答案 2 :(得分:2)
我同意你不需要一个完全成熟的数据库,因为似乎所有你想要的是原子文件写入。您需要分两部分来解决这个问题,序列化/反序列化和原子写作。
对于第一部分,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
时需要考虑这种可能性。
如果有可能有多个并发编写器,则必须考虑同步构造。
答案 3 :(得分:1)
由于您提到您的数据很小,我会使用一个简单的解决方案并使用pickle模块,它允许您将python对象转储到行very easily。
然后,您只需设置Thread,即可在定义的时间间隔内将对象保存到文件中。
不是“图书馆”解决方案,但是 - 如果我理解你的要求 - 简单到你真的不需要它。
编辑:你提到你想要涵盖写本身期间出现问题的情况,有效地使它成为一个原子事务。在这种情况下,传统的方法是使用“基于日志的恢复”。它本质上是将一条记录写入日志文件,说“写入事务已开始”,然后在完成后写入“写入事务”。如果“已启动”没有相应的“提交”,则回滚。在这种情况下,我同意使用像SQLite这样的简单数据库可能会更好。这可能是一种轻微的矫枉过正,但另一方面,自己实现原子性可能会重新发明轮子(我没有找到任何明显的库来为你做这件事)。
如果您决定采用狡猾的方式,本主题将在Silberschatz的操作系统手册的“原子事务处理”一节的“流程同步”一章中介绍。
一个非常简单(尽管可能不是“事务上完美”)的替代方案只是每次都记录到一个新文件,这样如果一个人破坏了你的历史。您甚至可以为每个文件添加校验和,以自动确定它是否已损坏。
答案 4 :(得分:0)