Jankov_n
Jankov_n

Reputation: 103

OdooV8 - Why does it take so long to create a record in 'res_partner' in my case

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 :

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

Answers (2)

Jankov_n
Jankov_n

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

Nguyen Vu
Nguyen Vu

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

Related Questions