从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 - 2,reset_value - 1, initial_value,initial_value + 1等。在这种情况下,每次调用 get_next_value必须提供initial_value和reset_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
- 初始稳定释放。