Il arrive un moment où aucune vue d'Odoo ne répond à la question posée : il faut croiser trois tables, agréger autrement, comparer à une période glissante. La réponse classique est de développer un module — plusieurs jours, et une dette à chaque montée de version.
bi_sql_editor propose l'autre chemin : on écrit la requête SQL, et le module fabrique tout le reste. Une vue PostgreSQL, un modèle Odoo, les droits, un menu, et des vues liste, pivot et graphique prêtes à l'emploi.
Résumé
À partir d'une requête SQL, le module fabrique tout le reste : une vue PostgreSQL, un modèle Odoo, les droits, un menu et des vues liste, pivot et graphique — sans écrire une ligne de Python.
Trois règles en conditionnent l'usage sain : préfixer chaque colonne en x_, poser la sécurité avant de générer l'interface — une requête SQL contourne les droits d'Odoo —, et documenter la requête, sans quoi elle devient dans deux ans un chiffre que personne ne sait plus expliquer.
L'essentiel
- Un workflow en 4 étapes : brouillon → requête validée → vue SQL et modèle créés → interface créée.
- Vue normale ou matérialisée : la seconde pour les requêtes lourdes, rafraîchie périodiquement.
- Convention obligatoire : chaque colonne de la requête doit être préfixée
x_. - Rôle pivot par champ : colonne, ligne ou mesure — c'est ce qui rend le tableau croisé exploitable.
- Droits par rapport : groupes autorisés et domaine supplémentaire, dont le filtrage multi-société.
- Outil d'administrateur : seul l'utilisateur admin est membre du groupe Manager par défaut.
Ce que le module ajoute à l'instance
| Élément | Nombre |
|---|---|
| Modèles créés | 2 |
| Modèles étendus | 1 |
| Champs ajoutés | 80 |
| Menus | 2 |
| Vues | 2 |
| Actions de fenêtre | 1 |
| Groupes de droits | 0 |
Deux modèles seulement, et ils suffisent à décrire le mécanisme :
| Objet | Ce qu'il est |
|---|---|
bi.sql.view | Le rapport : la requête, sa sécurité, son état dans le workflow |
bi.sql.view.field | Une colonne : son libellé Odoo, son type, son indexation, son rôle pivot |
Le module hérite du mixin sql.request.mixin fourni par sql_request_abstract : c'est lui qui assure la saisie et la validation de la requête — une requête invalide ne passe pas l'étape de contrôle.
Aucun groupe de droits n'est créé par ce module : il réutilise ceux de sql_request_abstract, ce qui est une bonne pratique mais rend la configuration des droits moins évidente à trouver.
Où le trouver dans Odoo
| Menu | Pour qui |
|---|---|
| Tableaux de bord ▸ Configuration ▸ Vues SQL | Groupe SQL Request / Manager — créer et modifier les rapports |
| Tableaux de bord ▸ Rapports SQL | Groupe SQL Request / User — consulter les rapports générés |
La séparation est nette et bien pensée : celui qui écrit le SQL n'est pas celui qui lit le rapport. Une fois le rapport généré, il apparaît comme n'importe quel menu Odoo pour les utilisateurs autorisés — ils ne savent même pas qu'il y a du SQL derrière.
Cas d'usage
Créer un rapport SQL de bout en bout
- Tableaux de bord ▸ Configuration ▸ Vues SQL, puis Nouveau.
- Renseigner Name (le nom lisible du rapport) et Technical Name (un suffixe technique, par exemple
marge_par_famille). - Onglet SQL Settings : écrire la requête dans le champ query, en préfixant chaque colonne sélectionnée par
x_— par exemplename as x_name. - Onglet Security : renseigner Allowed Groups, et si besoin un domaine dans Extra Rule Definition.
- Faire progresser l'enregistrement dans le workflow en cliquant sur les boutons successifs : validation de la requête, création de la vue SQL et du modèle, puis création de l'interface.

La convention x_ n'est pas un détail de style : c'est elle qui permet au module de distinguer les colonnes de la requête des champs techniques du modèle qu'il génère. Une colonne sans préfixe fait échouer la création.
Poser la sécurité avant de générer l'interface
C'est l'étape qu'on saute et qu'on regrette : un rapport SQL contourne les règles d'accès habituelles d'Odoo, puisqu'il interroge la base directement.
- Onglet Security, champ Allowed Groups : limiter explicitement les groupes qui verront le menu.
- Champ Extra Rule Definition : ajouter un domaine, notamment pour le filtrage multi-société.
Le filtrage multi-société est le cas à traiter systématiquement si vous avez plusieurs entités : un rapport SQL sans ce domaine montre les chiffres de toutes les sociétés à quiconque accède au menu. Le domaine prend la forme d'un filtre sur la colonne de société de votre requête, comparée aux sociétés autorisées de l'utilisateur.

Régler les champs pour un tableau croisé utilisable
C'est ce qui sépare un rapport consulté d'un rapport abandonné. Chaque colonne doit se voir attribuer un rôle.
- Onglet SQL Fields : pour chaque colonne renvoyée par la requête, renseigner le libellé affiché et le type Odoo.
- Indiquer si le champ doit être indexé — utile sur les colonnes servant aux filtres.
- Régler sa visibilité dans la vue liste.
- Lui donner son rôle dans la vue pivot et graphique : colonne, ligne, ou mesure.


Passer en vue matérialisée pour une requête lourde
Une vue SQL normale réexécute la requête à chaque affichage. Sur une requête qui agrège des millions de lignes, l'écran devient lent pour tout le monde.
La vue matérialisée stocke le résultat et se rafraîchit périodiquement. Le compromis est explicite : vous troquez la fraîcheur contre la vitesse. Pour un rapport de pilotage mensuel, c'est le bon choix ; pour un suivi d'encours à la journée, non.
Configuration et droits
- Installer le module — il dépend de
spreadsheet_dashboardet desql_request_abstract. - Attribuer les groupes de
sql_request_abstract, catégorie « SQL Request » : SQL Request / User pour consulter, SQL Request / Manager pour créer et modifier (ce dernier implique le premier). - Par défaut, seul l'utilisateur admin est membre du groupe Manager : c'est volontaire, et il faut le garder ainsi autant que possible.
Le dépôt le dit explicitement : ce module s'adresse à des profils techniques maîtrisant le SQL et le modèle de données d'Odoo, et son usage en production doit rester encadré. Ce n'est pas un outil de self-service pour utilisateurs métier — c'est un outil qui produit des rapports pour eux.
Limites connues
Le dépôt ne répertorie pas de défaut. Quatre limites d'usage, en revanche, déterminent si ce module est le bon choix pour votre besoin.
- Il contourne les règles d'accès d'Odoo. Une requête SQL lit la base directement : la sécurité repose entièrement sur les groupes autorisés et le domaine supplémentaire que vous posez.
- Il suppose de connaître le modèle de données. Les tables d'Odoo ne sont pas intuitives, et une jointure approximative produit des chiffres plausibles et faux.
- Une requête n'évolue pas avec Odoo. Si une montée de version change une table ou une colonne, le rapport casse — ou, pire, continue de répondre avec un sens différent. C'est un point à inscrire dans votre recette de montée de version.
- La vue matérialisée échange la fraîcheur contre la vitesse. Un rapport affiché à partir d'une vue matérialisée n'est pas à jour, et rien ne le signale à l'utilisateur.
La troisième est celle qu'on découvre le plus tard. Un rapport SQL écrit il y a deux ans, dont l'auteur est parti, et qui donne un chiffre que personne ne sait plus expliquer : c'est le même piège qu'un développement spécifique orphelin.
D'où une pratique simple : documentez la requête dans son propre champ Description — ce qu'elle compte, ce qu'elle exclut, et à quelle date elle a été écrite. Voir personnaliser ou rester sur le standard.
Quand préférer autre chose
| Besoin | Le bon outil |
|---|---|
| Un état financier par période, avec comparaison | mis_builder |
| Un croisement de données métier existantes | Les vues pivot natives d'Odoo |
| Une question posée une seule fois | Un export et un tableur |
| Un croisement que rien ne permet, à usage récurrent | bi_sql_editor |
| Une logique métier à calculer, pas seulement à lire | Un module développé |
La troisième ligne mérite d'être dite : beaucoup de rapports SQL sont écrits pour répondre à une question qui ne sera plus posée. Un export et un tableur coûtent une heure ; un rapport SQL coûte sa maintenance pour toujours.
Identité technique
| Nom technique | bi_sql_editor |
| Dépôt OCA | reporting-engine, branche 18.0 |
| Version du module | 18.0.1.0.4 |
| Licence | AGPL-3 |
| Dépendances | spreadsheet_dashboard, sql_request_abstract |
| Groupes utilisés | SQL Request / User, SQL Request / Manager |
Il fait partie de notre socle commun, et le dépôt reporting-engine fournit aussi report_xlsx et report_csv, également au socle.
Questions fréquentes
Faut-il savoir programmer pour utiliser bi_sql_editor ?
Il faut savoir écrire du SQL et connaître le modèle de données d'Odoo — pas du Python. Le dépôt le présente explicitement comme un outil pour profils techniques, et seul l'utilisateur admin est membre du groupe Manager par défaut. C'est un outil qui produit des rapports pour les utilisateurs métier, pas un outil en libre-service.
Pourquoi faut-il préfixer les colonnes par x_ ?
Parce que c'est ainsi que le module distingue les colonnes issues de votre requête des champs techniques du modèle Odoo qu'il génère. Une colonne sans ce préfixe fait échouer la création du modèle — écrivez name as x_name plutôt que name.
Un rapport SQL respecte-t-il les droits d'accès d'Odoo ?
Non, pas automatiquement : une requête SQL lit la base directement. La sécurité repose entièrement sur les Allowed Groups et l'Extra Rule Definition que vous posez dans l'onglet Security. En multi-sociétés, le domaine de filtrage par société est à traiter systématiquement.
Quand utiliser une vue matérialisée ?
Quand la requête est lourde et que la fraîcheur à la minute n'est pas nécessaire — un rapport de pilotage mensuel, par exemple. Le résultat est stocké et rafraîchi périodiquement, donc l'affichage est rapide mais pas à jour, et rien ne le signale à l'utilisateur.
Que devient mon rapport à la prochaine montée de version ?
C'est le vrai point d'attention : si une table ou une colonne change, le rapport casse — ou continue de répondre avec un sens différent, ce qui est plus grave. Inscrivez vos rapports SQL dans la recette de montée de version, et documentez chaque requête dans son champ Description.
Se faire accompagner
Écrire la requête est la partie courte. Les deux parties longues sont ailleurs : connaître le modèle de données d'Odoo assez bien pour que la jointure soit juste, et poser la sécurité — groupes autorisés, filtrage multi-société — avant de générer l'interface.
Nous écrivons ces rapports avec vous, nous documentons chaque requête, et nous les inscrivons dans la recette de montée de version pour qu'ils ne cassent pas en silence. Voir les prestations d'Atalios Consulting ou demander un rappel.
Pour aller plus loin
- mis_builder : construire ses propres états financiers
- Les trois indicateurs qui comptent, par métier
- Le socle commun : les 57 modules de chaque instance
En résumé
Une requête SQL, et le module fabrique la vue PostgreSQL, le modèle, le menu et les vues liste, pivot et graphique. Trois règles : préfixer les colonnes en x_, poser la sécurité avant de générer l'interface, et documenter la requête — sans quoi elle devient un chiffre que personne ne sait plus expliquer. Parlons de vos rapports.