干货!全网第一开源ERP Odoo生成唯一不重复的序列号解决方案

干货!全网第一开源ERP Odoo生成唯一不重复的序列号解决方案

未知 seo及sem资讯 2020年04月10日12时04分03秒

干货!跨网络的第一个开源ERP Odoo,可生成唯一的唯一序列号解决方案

在最近的项目中,需要使字段值根据记录生成的日期和特定的组合规则来生成序列号,该序列号不能重复,这最初是非常普遍的要求。只需对其进行编辑。由于未考虑巧合情况,因此在后续测试中发现了一个主要问题。如果用户同时启动生成的寄存器,则生成的序列号将被复制。

经过讨论和思考,有几种解决方案,一种是锁定数据库表面,一种是使用类似于redis的消息队列,另一种是使用文件锁定来达到排他数据库锁定的目标。考虑到项目的时间和当前情况,最终可以通过文件锁定来实现。

实际上,除了上述方法外,Odoo本身还具有一个模型(ir.sequence)来生成可以轻松达到此要求的序列,因为此模块以前从未接触过,并且在后续阶段仍在使用同事项目。到达并告诉我之后,我知道这是一件好事。在这里,我将记录使用文件锁的原始实现以及使用Odoo自己的ir.sequence的实现。

锁定文件-fcntl

fcntl是标准Python库中用于文件锁定的模块。以下功能主要用于实现中:

def flock(fd,操作):

“ “ “

群(fd,操作)

对文件描述符fd执行锁定操作。看到Unix

有关羊群(2)的手册,请参见详细信息。 (在某些系统中,此功能是

使用fcntl()进行仿真。)

“ “ “

通过

其中fd是文件描述符,而operation是锁定操作。有四种类型:

fcntl.LOCK_EX排他锁

fcntl.LOCK_NB非锁定锁

fcntl.LOCK_SH共享锁

fcntl.LOCK_UN-解锁

有关其他特定的fcntl内容,请参阅智能开源制造公司发布的Odoo开发手册。

看一下具体的实现。提供代码之前,请先描述要求。假设模型中存在一个字段sn,用于存储根据某些规则生成的序列号。序列号的组成规则如下:

固定前缀SN

以记录生成日期的6位数字y%m%d为171208,2017年12月8日

最后一个是一个三位数的序列号,从001开始

序列号不能重复

序列号的后3位数字每天自动重置,从001开始(此要求包括一些扩展名,因此本文将不满足此要求)

要求非常简单明了。让我们从下面的代码开始具体的实现。首先创建一个demo_sequence模块:

./odoo-bin-甲虫demo_sequence

然后在模块目录中创建一个数据库目录data /,在该目录中创建一个data.xml文件,该文件将在以后使用;继续在模块化目录中创建一个静态目录static /,并在该目录中创建一个空的SN文件。 LOCK用作锁定文件对象。完成后的目录结构如下:

demo_sequence

├──__init__.py

├──__manifest__.py

├──控制器

│├──__init__.py

│└──controllers.py

├──数据

│└──data.xml

├──演示

└──└──demo.xml

├──型号

│├──__init__.py

│└──models.py

├──安全

│└──ir.model.access.csv

├──静态

│└──SN.LOCK

└──意见

├──templates.xml

└──views.xml

模板和视图准备将在此处创建,稍后将给出特定的代码。首先,创建一个函数来锁定文件:

def file_file(标志= fcntl.LOCK_EX):

FILE_PATH = get_module_resource(“演示序列”,“静态/ SN.LOCK”)

文件=打开(FILE_PATH)

fcntl.flock(file.filename(),标志)

_logger.info(“获取锁”)

返回文件

然后替换creative()方法:

@ api.model

def创建自己:

文件=文件锁()

sn_prefix =“ SN” + datetime.date.today()。 strftime(“%y%m%d ”)

obj = self.env [“ demo_sequence.fcntl”]。 search_read([(“ sn”,“ = like”,sn_prefix +“%”)],限制= 1,顺序=“ sn DESC”)

#今天有序列号。最新序列号的增加

如果obj和obj [0] [“ sn”]。 beginwith(sn_prefix):

sn_suffix = int(obj [0] [“ sn”] [-3:])+ 1

vals [“ sn”] = sn_prefix + str(sn_suffix).zfill(3)#填充0

否则:

vals [“ sn”] = sn_prefix +“ 001”

res =超级(DemoSequence,self).create(vals)

#关闭文件会自动将其解锁

file.close()

一无所获

使用fcntl锁定文件,然后生成序列号并将其写入数据库中,以达到不重复序列号的目的,这是代码的工作方式,但是有一种更简单的方法将ir.sequence模型与Odoo结合使用。生成序列号。

独特的流派ID序列

ir.sequence模型对此进行了描述:

序列模型允许您定义和使用所谓的序列对象。

我们可以使用它来创建唯一的标识符。让我们看看如何使用ir.sequence达到上述要求。

打开data / data.xml并添加以下代码:

ltlt; xml版本= 1.0”编码=“ utf-8 “? gt;

ltlt; odoo >

ltlt;数据noupdate =“ 1 “ gt;

ltlt;寄存器ID = seq_demo_sequence_sn 型号=“ ir.sequence gt;

ltlt;字段名称= 名称“ gt;演示序列SN /字段

ltlt;字段名称= 代码“ gt; demo_sequence.sequence ult26; /字段

ltlt;字段名称= 前缀“ gt; SN%(y)s%(月)s%(天)s /字段

ltlt;字段名称= 完成“ gt; 3 lt; /字段

ltlt; /记录gt;

ltlt; /数据>

ltlt; / odoo >

实际上,在满足要求的前提下,此处的参数已远远超过这些参数。分别说明每个参数的作用:

名字-名字,随你想要

代码调用以生成必须唯一的加密密钥

prefix —可以是固定文字或组合参数的前缀

序列中位数的增加

注意:请记住将data / data.xml添加到__manifest__.py数据列表中

下一步是调用规则生成的序列号,并重写模型的create()方法:

@ api.model

def创建自己:

vals [“ sn”] = mem.env [“ ir.sequence”]。 next_by_code(“ demo_sequence.sequence”)

返回(DemoSequence2,self).create(vals)

显然,只需要一行代码即可获得唯一的序列号,这比以前使用fcntl锁定文件的方法要简单几个级别。此处的调用使用先前定义中编写的代码。

实际项目中使用的两种方法记录在这里。 OSCG的确是一件好事,看看您写的是什么,毕竟,在我很小的时候,我将介绍开源智能制造公司的功能。模块化源代码是改进Odoo的方法。据报道,在他们的官方网站上有他们的专家组编号组,并且有很多专家和优质咖啡一起为您解答无需技术的联系。

广告位
标签: