Reputation: 103
I recently started to develop with odoo8 and I've met a problem.
My problem is that I have two classes : 'helpdesk' and 'res_partner' and I don't know why my code stuck for a long time when I create a new record in 'res_partner' but when I comment this block of codes (below) my code works great.
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 has several fields and methods to get information, and computes them from the user inputs. Once the information computed, I create my record which is a new partner.
How I tried to solve my problem, I :
Launched odoo in shell mode with '--debug' option and a pdb where the code is stuck (it's stuck at the 'create' method as I said)
Read some threads and documentations about my problem, but most are in v7 for the create method and anybody has been stuck like this for the creation of a record
Checked each value that I sent to create my new record
Saw the behavior of records and how they are stored with phpPgAdmin
For more information, this is my entire method definition :
@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 !")
EDIT
After several attempts to debug my code with pdb, I noticed that something went wrong in the for statement when I compare firstnames and lastnames :
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
# Append element
Indeed, pdb blocks (2/3 sec) for each start of for statement before it gives me the hand back.
For example :
(pdb) ->if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
# stuck 2-3 seconds
(pdb) -> newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
This behavior continues for about the first iterations of the for statement, after this amount of iterations, this behavior is no longer adopted for the rest of the iterations. Once I arrived at the create statement (with pdb), the creation record is miraculously unlocked and the code works.
I still don't know why this problem occurs and I still don't know how to solve it.
Upvotes: 2
Views: 1145
Reputation: 103
I've found an answer for my question, and I think to know where the problem came from.
Where was my problem
So the problem came from my first for
statement which is :
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)
Theoretically nothing could be wrong with the for
and search
statements since they do what I want to do. But the problem is that each iteration that the program did in this for
was 'n' queries sent to the PostgresSQL server (where n
corresponds to the number of time that p
is used in each iteration. In my case n
= 2). This issue escalated quickly since search
returned me about a thousand of partners (which are represented by id
of each record saved in res.partner
that matched the search
query). So in the for
this corresponds to thousands of queries that I sent in a very short time to the PostgreSQL server, and it seems that this server couldn't handle this amount of requests in a very short time.
So the problem was not the code in himself, but the behavior that I gave to him. The result of that behavior gave another behavior to the PostgreSQL for the further queries that I will give via Odoo, like create
.
How I solved it
The solution for me was to use the psycopg2 module. This module allowing communication with the postgreSQL server. The main difference between both in my case was that Odoo stayed in communication with the PostgreSQL server even if I used search
to get only values that I wanted. While psycopg2
gived me a list
(of tuples
) that only contains "real" values and not an id
like Odoo gave me with search
.
Once again, I don't know if the solution that I choosed was the best or if the issue came from there like I said above but this solution works well for me and I hope it will help others users stuck in a problem with the same behavior.
Upvotes: 1
Reputation: 66
you got that issue because maybe you have compare 2 different type! In your case, you maybe try to compare between res_partner object and string type or another! That should be res.partner(2973,).id or res.partner(2973,).name ....
Upvotes: 1