从augustien的django序列派生而来,这个包旨在保持py2的兼容性。

django-sequences-py2的Python项目详细描述


问题

django的默认隐式主键不能保证是连续的。

如果事务插入一行,然后回滚,则序列计数器 不会因为性能原因而回滚,从而在主键中造成间隙。

这可能会导致某些用例(如会计)的遵从性问题。

这种风险并不为人所知。因为大多数事务都成功了,所以值看起来 相继的。只有通过审计才能发现差距。

解决方案

django序列只提供一个函数get_next_value,它是 设计用途如下:

from django.db import transaction

from sequences import get_next_value

from invoices.models import Invoice

with transaction.atomic():
    Invoice.objects.create(number=get_next_value('invoice_numbers'))

只有在调用^{tt1}时,django序列的保证才适用$ 并将其返回值保存到同一事务中的数据库!

安装

安装django序列:

$ pip install django-sequences-py2

将其添加到项目设置中的应用程序列表:

INSTALLED_APPS += ['sequences.apps.SequencesConfig']

运行迁移:

$ django-admin migrate

API

get_next_value生成一个无间隙的整数值序列:

>>> get_next_value()
1
>>> get_next_value()
2
>>> get_next_value()
3

它支持多个独立序列:

>>> get_next_value('cases')
1
>>> get_next_value('cases')
2
>>> get_next_value('invoices')
1
>>> get_next_value('invoices')
2

第一个值默认为1。它可以定制:

>>> get_next_value('customers', initial_value=1000)  # pro growth hacking

只有在调用get_next_value时,initial_value参数才重要 对于给定序列的第一次-假设对应的数据库 事务被提交;如上所述,如果事务被滚动 返回,生成的值不会被消耗。也可以初始化 数据迁移中的序列,而不是在实际代码中使用initial_value

序列可以循环:

>>> get_next_value('seconds', initial_value=0, reset_value=60)

当序列到达reset_value时,它将在initial_value重新启动。 在其他工作中,它生成reset_value - 2reset_value - 1initial_valueinitial_value + 1等。在这种情况下,每次调用 get_next_value必须提供initial_valuereset_value

为给定序列调用get_next_value的数据库事务是 已序列化。换句话说,当您在数据库中调用get_next_value时 事务,试图从同一序列中获取值的其他调用方 将阻塞,直到事务完成,无论是提交还是回滚。 您应该缩短此类事务以将对性能的影响降到最低。

传递nowait=True将导致get_next_value引发异常 而不是封锁。这很少有用。也不适用于 第一个电话。(可以说这是个错误。欢迎使用修补程序。)

为不同序列调用get_next_value不会与一个序列交互 另一个。

最后,通过using='...'可以选择 存储当前序列值。如果未提供此参数,则 当前值存储在默认数据库中,用于写入 sequences应用程序。详情见下文。

总之,get_next_value的完整签名是:

get_next_value(sequence_name='default', initial_value=1, reset_value=None,
               *, nowait=False, using=None)

在幕后,它依赖于数据库的事务完整性 保证每一个值都会返回一次。

贡献

您可以使用以下命令运行测试:

$ make test

如果你想贡献,请在github上打开一个问题或请求!

其他数据库

INTEGER PRIMARY KEY AUTOINCREMENTsqlite上的字段没有此问题。

作者不知道这个问题是否会发生在mysql或oracle上。如果它 是的,那么django序列的当前实现应该可以工作。如果你 测试这个,请在github上打开一个问题来报告您的发现。请注意 mysql不支持nowait参数。

多个数据库

因为django序列依赖于数据库来保证事务性 完整性,给定序列的当前值必须存储在 数据库作为包含生成值的模型。

在使用多个数据库的项目中,必须编写适当的数据库 路由器为所有数据库上的sequences应用程序创建表 存储包含序列号的ing模型。

每个数据库都有自己的命名空间:存储在 两个数据库在每个数据库中都有独立的计数器。

更改日志

2.2

  • PostgreSQL优化性能≥9.5。

2.1

  • 使用reset_value提供循环序列。

2.0

  • 添加对多个数据库的支持。
  • 添加翻译。
  • nowait成为仅关键字参数。
  • 放弃对python 2的支持。

1.0

  • 初始稳定释放。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java JPanel不会对键绑定做出反应   当时间大于零时,不得在UI线程上调用java Await   JTextArea的java线程安全。追加   Java用户输入的字和行计数器   java以spreedsheat格式将数据保存到文件中   java构造函数的意义是什么?   java findViewById返回null,尽管组件的ID存在   java如何向按钮添加图像   java如何中断ExecutorService的线程   java如何将属性(例如枚举)绑定到不同类型的组件属性(例如每个枚举的映像)?   随机森林分类器的java实现   html使用java连接到一个站点并发布,HTTP状态代码200   从类访问属性时发生java编译错误   Java自动填充ArrayList,搜索更好的选项