Search code examples
pythonodooodoo-12

Convert sql query to ORM Odoo


I have a function in a model file for the ODOO framework. I just came across SQL queries within my functions. I just want to convert the SQL query to ORM with Odoo framework. Like, create, search, browse inbuilt functions that it already has. I just need some examples for the two queries I have in the below function like how we convert it to ORM with GOOD explanation. so that I can carry forward the same with other queries as well.

Function:

def bill(self,data):

    id = data.get('id', False)
    if data:
        chge = []
        s_Date = data['start_date']
        e_Date = data['end_date']
        query = """SELECT "endpoll","table_name","kcp","plan","startpoll",id FROM 
        bill WHERE ((("endpoll" >= '%s')  OR  "endpoll" IS NULL )  AND  ("startpoll" <= '%s')  AND  
        ("customer" = %s)  AND  ("active" in ('Y','N'))) ORDER BY "startpoll" """ % (
        s_Date, e_Date, id)
        self._cr.execute(query)
        status_records = self._cr.dictfetchall()
        if not status_records:
            return []
        gst = 0
        for records in status_records:
            icp_id = record['ikp']
            varcharge = 0
            query2 = """SELECT "read_date" FROM dailycharges WHERE (("billstatus" = %s)  
            AND  ("status" = 'B')) ORDER BY "read_date" desc limit 1""" % (
                record['id'])
            self._cr.execute(query2)
            maxbill = self._cr.fetchone()
            if maxbill:
                unbill = datetime.strptime(maxbill[0]

            else:
                unbill = record['Start_Date']
            start_date = max(invoice_start_date, str(unbill))

    return data

There are two simple queries within this function. I need them to be converted into ORM. Thanks in advance.


Solution

  • They could be replaced with the search method. WHERE clause will be converted to a search domain, ORDER BY will be replaced with order parameter (order='read_date desc') and the LIMIT clause is available as a parameter (limit='1').

    For example, the second select query could be replaced with:

    record = self.env['dailycharges'].search([('billstatus', '=', record['id']), ('status', '=', 'B')], order='read_date DESC', limit=1)
    # read_date = record.read_date
    

    Edit:
    You can use the search_read method which allow you to specify the fields to read.

    Odoo provides a search_read() shortcut which as its name suggests is equivalent to a search() followed by a read(), but avoids having to perform two requests and keep ids around.

    Its arguments are similar to search()’s, but it can also take a list of fields (like read(), if that list is not provided it will fetch all fields of matched records)

    Example:

    self.env['dailycharges'].search_read([('billstatus', '=', record['id']), ('status', '=', 'B')], ['read_date'], order='read_date DESC', limit=1)
    
    [{'id': ?, 'read_date': ?}]