强大的、原子的单文件值存储
项目描述
atomic_store
比DBMS更容易,但比单个文件更具有容错性。
有时您需要在执行之间管理一些状态。有时,一个完整的数据库可能过于复杂。
这个库可以轻松地将东西存储在JSON文件中,以原子和容错的方式。
也支持其他格式(如pickle和bson),并且可以支持任意格式。
目录
安装
只需pip install atomic_store
。或者,如果您必须,请使用pip install -r requirements.txt
请注意,唯一的依赖项是atomicwrites
,它没有依赖项。
使用
默认情况下,存储库以json编码,写入临时文件,然后原子性地替换旧文件。在读取时,如果文件不存在,则使用默认值。默认默认值是None
。
上下文管理器
此程序记住所有开始时间
import atomic_store
import time
with atomic_store.open('runs.json', default=[]) as store:
print('Previous executions:')
print(store.value)
new_entry = time.strftime('%Y-%m-%d %H:%M:%S%z')
store.value.append(new_entry)
离开上下文管理器将处理所有写入。中间值不会写入磁盘。
如果任务运行时间短,或者在任何错误发生时您只想保留旧状态,这将是理想的。
有关高级用法,请参阅重入性部分的子部分。
手动控制
此程序记住所有开始时间
import atomic_store
my_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 文件尽可能保持小,可以调用 open
并使用 dump_kwargs=dict(separators=(',', ':'))
。也存在 load_kwargs
关键字。
非 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
作为上下文管理器多次使用,默认行为是在最后一个 with
退出时才写入文件。
# Assume `state.json` contains only `"before"`.
mngr = atomic_store.open('mystate.json', default=[])
with mngr as store:
store.value = 'outer'
# File contains `"before"`: We haven't exited any context manager yet.
with mngr as store:
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)
with mngr as store:
store.value = 'outer'
# File contains `"before"`: We haven't exited any context manager yet.
with mngr as store:
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
更高级的语义。 - 这包括回滚。当文件不存在时,哪个行为是期望的并不明显(重用
default
值?如果像列表和字典那样修改了它怎么办?),以及堆叠的上下文管理器(应该回滚到文件的状态吗?还是到with
的开始处?)
贡献
请随时参与进来! 新建一个问题 或提交 PR。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。
源分布
构建分布
atomic_store-0.0.1.tar.gz 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 3ce00b2819f3ee3207de79c2aeb66aee1566a4c1fdbae317c72d0ff20a3729e5 |
|
MD5 | 662660607425ad6223d791b78f9c2ad0 |
|
BLAKE2b-256 | e44a934ebb885d353c63d2b3f2eeda6c7fc01e254685a07c4e16947224754114 |