La importancia de saber SQL en Odoo

2 de setiembre de 2023 por
Gustavo Orrillo
| Sin comentarios aún
 

Dentro de la lista de conocimientos que debe manejar un programador de Odoo hay que agregarle SQL. Por que? Al fin y al cabo, el ORM no nos abstrae de dicha necesidad? Si bien esto es verdad, SQL nos brinda herramientas muy útiles para nuestras tareas diarias desarrollando y manteniendo funcionalidades de Odoo.

En que podemos utilizar SQL? Algunos motivos que se me vienen a la mente ahora son...

  • Creación de vistas de Odoo a partir de vistas SQL, para facilitar las consultas de los usuarios. Era una técnica utilizada por Odoo hasta versiones anteriores y que describimos en "Como crear consultas en Odoo".
  • Actualizar datos en la base de datos con un utilitario de SQL, como por ejemplo psql o pgadmin. Tarde o temprano, por razones inesperadas nos vemos forzados a realizar UPDATEs en forma manual. Y para ello necesitamos saber SQL. Un gran ejemplo de esto puede ser como recuperar el password de admin, como lo describimos en el post "Ayuda! ya no me acuerdo del password de admin!!!"
  • Si bien el ORM es fantástico, su velocidad muchas veces deja mucho que desear. Es por ello que debemos recurrir a SQL salteando el ORM. Para darles un ejemplo, computar un campo many2one utilizando triggers en lugar de un método que utiliza el ORM. No hice las mediciones pero no cabe duda que es más rápido
  • Creacion de reportes ad-hoc. Uno puede conectar Odoo a PowerBI o ejecutar cualquier SQL mediante herramientas como psql o pgadmin, lo que le brindará un archivo CSV el cual se puede utilizar con Excel para crear reportes. Esto requiere de comprender el modelo de datos de Odoo, el cual honestamente no tiene grandes secretos. Una vez que uno comprende la lógica del negocio es facil interpretarlo.

Como es aprender SQL?

Creanme que es muy sencillo. Yo primero aprendí a programar en Basic (en una ZX Spectrum y una Commodore 64)  y luego aprendí SQL en un Mainframe (utilizando una herramienta que tenia el inolvidable nombre de SPUFI). Era muy facil de aprender la sintaxis pero ademas era alentador obtener resultados de manera inmediata. Uno no debía superar la frustración de una gran curva de aprendizaje, ya que apenas uno comprendía la sintaxis de un SELECT ya empezaba a ser productivo.

Lo mismo sucede con Odoo.  En el caso de Odoo uno no necesita ser un experto en SQL, si debe conocer como realizar un SELECT y como hacer el join con las tablas relacionadas. Tambien debe saber como ejecutar un UPDATE (realizar INSERTs o DELETEs es mas complejo ya que uno debe tener en cuenta los lineamientos del ORM para no romper la integridad de la base de datos) ya que de vez en cuando necesitamos realizar algunas tareas de mantenimiento de datos. No se necesita conocer como crear tablas ni alterar la estructura de las mismas ya que de eso se ocupa el ORM. Por último, es muy util comprender como crear indices y saber en que circumstancias crearlos. 

Ejemplos de uso de Odoo con SQL

No es complicado, hay que saber utilizarlo. Si uno quiere ejemplo de como se utiliza puede ver el código del archivo account.py del módulo account de Odoo. Por ejemplo podemos encontrar el código para computar tres campos llamados opening_debit, opening_credito y opening_balance

    def _compute_opening_debit_credit(self):
self.opening_debit = 0
self.opening_credit = 0
self.opening_balance = 0
if not self.ids:
return
self.env.cr.execute("""
SELECT line.account_id,
SUM(line.balance) AS balance,
SUM(line.debit) AS debit,
SUM(line.credit) AS credit
FROM account_move_line line
JOIN res_company comp ON comp.id = line.company_id
WHERE line.move_id = comp.account_opening_move_id
AND line.account_id IN %s
GROUP BY line.account_id
""", [tuple(self.ids)])
result = {r['account_id']: r for r in self.env.cr.dictfetchall()}
for record in self:
res = result.get(record.id) or {'debit': 0, 'credit': 0, 'balance': 0}
record.opening_debit = res['debit']
record.opening_credit = res['credit']
record.opening_balance = res['balance']​

Donde se puede ver como se ejecuta un SELECT sobre la tabla account_move_line que sumariza los débitos y créditos para las cuentas seleccionadas. Luego el resultado sumarizado se utiliza para actualizar los campos computados. Hacer lo mismo utilizando el ORM tendría la siguiente forma:

amls = self.env['account.move.line'].search([('account_id','=',self.ids)])
record.opening_credit = sum(amls.mapped('credit'))
record.opening_debit = sum(amls.mapped('debit'))
record.opening_balance = sum(amls.mapped('balance'))

A nivel funcional termina siendo lo mismo pero a nivel performance es lento. Primero lee todos los apuntes contables para una cuenta determinada. Y despues todos esos apuntes son sumarizados tres veces diferentes Por Odoo. Usando SQL la operación se realiza una sola vez en el servidor de base de datos (la cual se encuentra mejor optimizada para procesamietno que Odoo) y solo se devuelven los resultados una sola vez.

Quiza para probar mi punto, Odoo cuenta con el método read_group el cual hace practicamente lo mismo

res = self.read_group(
[('account_id', "in", self.ids)], #domain
​['account_id', 'debit:sum', 'credit:sum', 'balance:sum'], #fields
​['account_id'] #group_by​
)
for record in self:
​res = result.get(record.id) or {'debit': 0, 'credit': 0, 'balance': 0}
​record.opening_debit = res['debit']
​record.opening_credit = res['credit']
​record.opening_balance = res['balance']

El método read_group del ORM internamente hace un SELECT y GROUP BY (como pueden ver en su sintaxis). Ahora para saber usarlo, uno debe tener conocimiento de la sentencia SELECT de SQL

Por último, una vez hablé con un amigo que trabajó en una empresa que administraba el backend de un servicio de delivery en Medio Oriente. Mi amigo me comentó que la única manera de resolver los problemas de performance que se presentaban debido a los volumenes de datos que manejaban era mediante SQL, bypaseando el ORM.

Es por cosas como estas que necesitamos aprender SQL. No es complicado como acabo de decir, y los beneficios pueden ser muy grandes.

Gustavo Orrillo 2 de setiembre de 2023
Compartir
Archivar
Identificarse dejar un comentario