一个健壮的原子单文件值存储
atomic-store的Python项目详细描述
原子商店
Easier than a DBMS, but more fault-resistant than just a file.
有时候你需要在执行过程中管理一些状态。 有时候,一个完全成熟的数据库实在是太多了。
这个库使在json文件中保存store的内容变得容易, 以原子性和抗故障的方式。
其他格式(如pickle和bson)也受支持, 任意格式也是可能的。
目录
安装
只要pip install atomic_store
。或者,如果必须的话,pip install -r requirements.txt
注意,唯一的依赖项是atomicwrites
,它没有依赖项。
用法
默认情况下,存储编码为json,写入临时文件,
然后原子地替换旧文件。读取时,如果文件
不存在,使用默认值。默认默认值是None
。
上下文管理器
此程序记住所有开始时间:
importatomic_storeimporttimewithatomic_store.open('runs.json',default=[])asstore:print('Previous executions:')print(store.value)new_entry=time.strftime('%Y-%m-%d %H:%M:%S%z')store.value.append(new_entry)
离开上下文管理器会处理所有写操作。 没有中间值写入磁盘。
如果任务很短,并且出现任何错误,这是理想的 不管怎样,你只想保持旧的状态。
有关高级用途,请参见reentrancy小节。
手动控制
此程序记住所有开始时间:
importatomic_storemy_store=atomic_store.open('gathered.json',default=dict())my_store.value['state']='running'my_store.value['thought']='I would not eat green eggs and ham.'my_store.commit()# ... some calculations ...my_store.value['state']='done'my_store.value['thought']='I do so like Green eggs and ham!'my_store.commit()
只有对commit()
的调用才会导致对磁盘的写入。
同样,没有中间值被写入磁盘。
如果你有一份长期工作,步骤清晰, 每一步的成果都是有价值的。
请注意,commit()
在上下文管理器中也可用。
格式调整
如果您使用的是json后端,并且希望让json文件尽可能小,
您可以用dump_kwargs=dict(separators=(',', ':'))
调用open
。
关键字{{CD9}}也存在。
非json格式
您可以使用任意其他格式,使用format
关键字:
atomic_store.open('runs.json',default=[],format=MY_FORMAT)
支持的值是None
(对于json),'json'
,'pickle'
,
'bson'
(需要安装bson),以及任何模块或对象
提供dump/load
或dumps/loads
。
默认情况下,atomic_store
假设您对二进制文件进行操作,除非涉及json。
要覆盖此项,可以设置is_binary
。
注意,这意味着您可以按原样使用模块json
、pickle
和bson
。
为了方便起见,还可以重写抽象类
atomic_store.AbstractFormatFile
或atomic_store.AbstractFormatBstr
。
在所有情况下,仍然支持load_kwargs
和dump_kwargs
。
可重入性
如果同一个atomic_store
被多次用作上下文管理器,
默认行为是只在最后的^ {{CD27>}退出时写入文件:
# Assume `state.json` contains only `"before"`.mngr=atomic_store.open('mystate.json',default=[])withmngrasstore:store.value='outer'# File contains `"before"`: We haven't exited any context manager yet.withmngrasstore:store.value='inner'# File contains `"before"`: We haven't exited any context manager yet.# File now contains `"inner"`, because the inner `with`-statement wrote it.# Read the Reentrancy section if you consider this undesired behavior.# File now contains `"inner"`, because the outer `with`-statement wrote it again.
如果您认为这种行为不受欢迎,您可以只使用多个上下文管理器(多次调用atomic_store.open
),或者使用关键字ignore_inner_exits=True
,如下所示:
# Assume `state.json` contains only `"before"`.mngr=atomic_store.open('mystate.json',default=[],ignore_inner_exits=True)withmngrasstore:store.value='outer'# File contains `"before"`: We haven't exited any context manager yet.withmngrasstore:store.value='inner'# File contains `"before"`: We haven't exited any context manager yet.# File *still* contains `"before"`, as the manager detected that it is still active.# File now contains `"outer"`, because the outer `with`-statement wrote it.
原子不是魔法
这个图书馆并不神奇。
如果两个线程(或两个进程,或其他什么)打开一个存储, 修改某些内容,然后并发写入,其中一个结果可能会丢失。 但是,写操作保证是原子的, 因此,数据只是丢失,而不是损坏。
待办事项
- 找出如何使
bson
成为可选的 - 在pypi上发布
不允许
以下是此项目不支持的一些内容:
- 任何数据库后端。
- 任何多文件后端。
- 比
commit
更高级的语义。 - 这包括回滚。当文件不存在时,不清楚哪些行为是需要的(重新使用^ {CD32>}值)?如果它被修改了,比如列表和听写呢?),并使用堆叠的上下文管理器(是否应回滚到文件的状态?或者到
with
的开头?
贡献
尽情潜水吧!Open an issue或提交prs。