OdooV8 - 为什么在 'res_partner' 中创建记录需要这么长时间
OdooV8 - Why does it take so long to create a record in 'res_partner' in my case
我最近开始使用odoo8进行开发,但遇到了一个问题。
我的问题是我有两个 class:'helpdesk' 和 'res_partner'我不知道为什么当我在 'res_partner' 中创建新记录时,我的代码会卡住很长时间,但是当我评论这段代码(如下)时,我的代码运行良好。
self.env['res.partner'].create({
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
})
'helpdesk' class 有几个字段和方法来获取信息,并根据用户输入计算它们。一旦信息计算出来,我就创建了我的记录,这是一个新的合作伙伴。
我是如何尝试解决我的问题的:
在 shell 模式下使用“--debug”选项和代码卡住的 pdb 启动了 odoo(它卡在 'create'方法如我所说)
阅读一些关于我的问题的线程和文档,但大多数都在 v7 中用于 create 方法,任何人都被困在这样的创建记录
检查了我为创建新记录而发送的每个值
看到了记录的行为以及它们是如何用 phpPgAdmin 存储的
有关更多信息,这是我的整个方法定义:
@api.one
def addPartnerInDB(self):
if (not self.firstNameOfUser or
not self.lastNameOfUser or
not self.dobOfUser or
not self.pBirthOfUser):
raise ValidationError(u"Tous les champs sp\u00E9cifi\u00E9s pour "
u"cette demande doivent \u00EAtre remplis !")
# Avoid concurrent drop-down
self.dropDownList1 = False
self.dropDownList3 = False
# Get every partners
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
# Avoid useless compute for each iteration
newDateFmt = u"".join(datetime.datetime\
.strptime(str(self.dobOfUser), "%Y-%m-%d")\
.strftime("%d/%m/%Y"))
newFNameFmt = self.firstNameOfUser.strip().replace(" ", "-").lower()
newLNameFmt = self.lastNameOfUser.strip().replace(" ", "-").lower()
newBPFmt = self.pBirthOfUser.strip().replace(" ", "-").lower()
matchedPartners = []
# Fetch partner specified by the user
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
partnerAlreadyExist = False
# If the list is not empty, then the fetch is enhance
if (matchedPartners):
for m in matchedPartners:
partnerDOB = False
partnerBP = False
if (not isinstance(m.birthdate, bool)):
if (newDateFmt == m.birthdate):
partnerDOB = True
if (not isinstance(m.birth_place, bool)):
if ((newBPFmt
== m.birth_place.strip().replace(" ", "-").lower())):
partnerBP = True
# If one of them it's true, the user already exist
if (partnerDOB or partnerBP):
partnerAlreadyExist = True
# Avoid useless iteration
break
# If the user specified doesn't exist he's created
if (not partnerAlreadyExist):
# Encode the string to avoid UnicodeError and further string errors
nameFmt = (self.lastNameOfUser.strip().upper(),
+ u" "
+ self.firstNameOfUser.strip().lower().title())
self.env['res.partner'].create(
{
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
}
)
else:
raise ValidationError(u"L'utilisateur renseign\u00E9 "
u"existe d\u00E9j\u00E0 !")
编辑
在多次尝试使用 pdb 调试我的代码后,我注意到在比较名字和姓氏时 for 语句中出现了问题:
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
# Append element
确实,在 for 语句的每次启动时,pdb 都会阻塞(2/3 秒),然后才会将手还给我。
例如:
(pdb) ->if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
# stuck 2-3 seconds
(pdb) -> newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
这种行为在 for 语句的第一次迭代中持续,在这个迭代次数之后,这种行为不再被用于其余的迭代。一旦我到达 create 语句(使用 pdb),创建记录就奇迹般地解锁并且代码工作。
我仍然不知道为什么会出现这个问题,我仍然不知道如何解决它。
你遇到这个问题是因为你可能比较了两种不同的类型!在您的情况下,您可能会尝试比较 res_partner 对象和字符串类型或其他类型!那应该是 res.partner(2973,).id 或 res.partner(2973,).name ....
我找到了问题的答案,我想知道问题出在哪里。
Where was my problem
所以问题来自我的第一个 for
语句,它是:
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
从理论上讲,for
和 search
语句不会有任何问题,因为它们做了我想做的事情。但问题是,程序在此 for
中执行的每次迭代都是 'n' 发送到 PostgresSQL 服务器的查询(其中 n
对应于 p
的次数在每次迭代中使用。在我的例子中 n
= 2)。这个问题迅速升级,因为 search
返回给我大约一千个合作伙伴(由 res.partner
中保存的与 search
查询匹配的每条记录的 id
表示)。所以在 for
这对应于我在很短的时间内向 PostgreSQL 服务器发送了数千个查询,而且这个服务器似乎无法在很短的时间内处理这么多的请求。
所以问题不在于他的代码,而是我给他的行为。该行为的结果为 PostgreSQL 提供了另一种行为,用于我将通过 Odoo 提供的进一步查询,例如 create
.
How I solved it
我的解决方案是使用 psycopg2 模块。该模块允许与 postgreSQL 服务器通信。在我的例子中,两者之间的主要区别是 Odoo 与 PostgreSQL 服务器保持通信,即使我使用 search
只获取我想要的值。虽然 psycopg2
给了我一个 list
(属于 tuples
),它只包含 "real" 个值,而不是像 Odoo 给我的 search
那样的 id
。
再一次,我不知道我选择的解决方案是否是最好的,或者问题是否像我上面所说的那样来自那里,但这个解决方案对我来说效果很好,我希望它能帮助其他陷入困境的用户相同行为的问题。
我最近开始使用odoo8进行开发,但遇到了一个问题。
我的问题是我有两个 class:'helpdesk' 和 'res_partner'我不知道为什么当我在 'res_partner' 中创建新记录时,我的代码会卡住很长时间,但是当我评论这段代码(如下)时,我的代码运行良好。
self.env['res.partner'].create({
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
})
'helpdesk' class 有几个字段和方法来获取信息,并根据用户输入计算它们。一旦信息计算出来,我就创建了我的记录,这是一个新的合作伙伴。
我是如何尝试解决我的问题的:
在 shell 模式下使用“--debug”选项和代码卡住的 pdb 启动了 odoo(它卡在 'create'方法如我所说)
阅读一些关于我的问题的线程和文档,但大多数都在 v7 中用于 create 方法,任何人都被困在这样的创建记录
检查了我为创建新记录而发送的每个值
看到了记录的行为以及它们是如何用 phpPgAdmin 存储的
有关更多信息,这是我的整个方法定义:
@api.one
def addPartnerInDB(self):
if (not self.firstNameOfUser or
not self.lastNameOfUser or
not self.dobOfUser or
not self.pBirthOfUser):
raise ValidationError(u"Tous les champs sp\u00E9cifi\u00E9s pour "
u"cette demande doivent \u00EAtre remplis !")
# Avoid concurrent drop-down
self.dropDownList1 = False
self.dropDownList3 = False
# Get every partners
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
# Avoid useless compute for each iteration
newDateFmt = u"".join(datetime.datetime\
.strptime(str(self.dobOfUser), "%Y-%m-%d")\
.strftime("%d/%m/%Y"))
newFNameFmt = self.firstNameOfUser.strip().replace(" ", "-").lower()
newLNameFmt = self.lastNameOfUser.strip().replace(" ", "-").lower()
newBPFmt = self.pBirthOfUser.strip().replace(" ", "-").lower()
matchedPartners = []
# Fetch partner specified by the user
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
partnerAlreadyExist = False
# If the list is not empty, then the fetch is enhance
if (matchedPartners):
for m in matchedPartners:
partnerDOB = False
partnerBP = False
if (not isinstance(m.birthdate, bool)):
if (newDateFmt == m.birthdate):
partnerDOB = True
if (not isinstance(m.birth_place, bool)):
if ((newBPFmt
== m.birth_place.strip().replace(" ", "-").lower())):
partnerBP = True
# If one of them it's true, the user already exist
if (partnerDOB or partnerBP):
partnerAlreadyExist = True
# Avoid useless iteration
break
# If the user specified doesn't exist he's created
if (not partnerAlreadyExist):
# Encode the string to avoid UnicodeError and further string errors
nameFmt = (self.lastNameOfUser.strip().upper(),
+ u" "
+ self.firstNameOfUser.strip().lower().title())
self.env['res.partner'].create(
{
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
}
)
else:
raise ValidationError(u"L'utilisateur renseign\u00E9 "
u"existe d\u00E9j\u00E0 !")
编辑
在多次尝试使用 pdb 调试我的代码后,我注意到在比较名字和姓氏时 for 语句中出现了问题:
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
# Append element
确实,在 for 语句的每次启动时,pdb 都会阻塞(2/3 秒),然后才会将手还给我。
例如:
(pdb) ->if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
# stuck 2-3 seconds
(pdb) -> newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
这种行为在 for 语句的第一次迭代中持续,在这个迭代次数之后,这种行为不再被用于其余的迭代。一旦我到达 create 语句(使用 pdb),创建记录就奇迹般地解锁并且代码工作。
我仍然不知道为什么会出现这个问题,我仍然不知道如何解决它。
你遇到这个问题是因为你可能比较了两种不同的类型!在您的情况下,您可能会尝试比较 res_partner 对象和字符串类型或其他类型!那应该是 res.partner(2973,).id 或 res.partner(2973,).name ....
我找到了问题的答案,我想知道问题出在哪里。
Where was my problem
所以问题来自我的第一个 for
语句,它是:
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
从理论上讲,for
和 search
语句不会有任何问题,因为它们做了我想做的事情。但问题是,程序在此 for
中执行的每次迭代都是 'n' 发送到 PostgresSQL 服务器的查询(其中 n
对应于 p
的次数在每次迭代中使用。在我的例子中 n
= 2)。这个问题迅速升级,因为 search
返回给我大约一千个合作伙伴(由 res.partner
中保存的与 search
查询匹配的每条记录的 id
表示)。所以在 for
这对应于我在很短的时间内向 PostgreSQL 服务器发送了数千个查询,而且这个服务器似乎无法在很短的时间内处理这么多的请求。
所以问题不在于他的代码,而是我给他的行为。该行为的结果为 PostgreSQL 提供了另一种行为,用于我将通过 Odoo 提供的进一步查询,例如 create
.
How I solved it
我的解决方案是使用 psycopg2 模块。该模块允许与 postgreSQL 服务器通信。在我的例子中,两者之间的主要区别是 Odoo 与 PostgreSQL 服务器保持通信,即使我使用 search
只获取我想要的值。虽然 psycopg2
给了我一个 list
(属于 tuples
),它只包含 "real" 个值,而不是像 Odoo 给我的 search
那样的 id
。
再一次,我不知道我选择的解决方案是否是最好的,或者问题是否像我上面所说的那样来自那里,但这个解决方案对我来说效果很好,我希望它能帮助其他陷入困境的用户相同行为的问题。