跳转到主要内容

强大的、原子的单文件值存储

项目描述

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/loaddumps/loads 的模块或对象。默认情况下,atomic_store 假设您操作的是二进制文件,除非涉及 JSON。要覆盖此行为,您可以设置 is_binary。请注意,这意味着您可以使用 jsonpicklebson 模块而不需要额外的设置。

为了方便起见,您还可以覆盖抽象类 atomic_store.AbstractFormatFileatomic_store.AbstractFormatBstr

在所有情况下,load_kwargsdump_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 (6.6 kB 查看散列

上传时间

构建分布

atomic_store-0.0.1-py3-none-any.whl (8.0 kB 查看散列

上传时间 Python 3

支持者