Introduction
Si vous avez travaillé avec Odoo assez longtemps, il y a de fortes chances que vous ayez rencontré l'infâme :
ValueError : Singleton attendu
C'est l'une des erreurs les plus courantes liées à l'ORM dans Odoo. Elle apparaît lorsqu'une méthode s'attend à un seul enregistrement mais reçoit plusieurs enregistrements à la place. Bien que le message d'erreur puisse sembler technique, la cause profonde est généralement simple une fois que vous comprenez comment fonctionnent les recordsets d'Odoo.
Ce guide explique ce que signifie l'erreur « Singleton attendu », pourquoi elle se produit et comment la corriger en toute sécurité sans compromettre votre logique métier ou vos intégrations.
Que signifie « Singleton attendu » dans Odoo ?
Le framework ORM (Object Relational Mapping) d'Odoo ne fonctionne pas par défaut sur des objets uniques. Au lieu de cela, il fonctionne avec des recordsets, qui peuvent contenir :
- Un enregistrement
- Plusieurs enregistrements
- Aucun enregistrement
Lorsque Odoo exécute une méthode conçue pour fonctionner sur un seul enregistrement, mais que l'ensemble d'enregistrements contient plusieurs enregistrements, cela génère une erreur :
ValueError : Singleton attendu
En termes simples :
Odoo s'attendait à un enregistrement. Il en a reçu plusieurs.
Cette erreur apparaît généralement dans :
- Les journaux du serveur
- Méthodes de module personnalisé
- Champs calculés
- Actions de bouton
- Actions automatisées
- Mises à jour en masse
Comprendre le comportement des recordsets est essentiel pour le corriger correctement.
Pourquoi cette erreur se produit-elle ?
1. Mauvaise compréhension des recordsets
Dans Odoo, self est presque toujours un recordset.
Même si vous pensez que vous opérez sur un seul enregistrement, Odoo pourrait appeler votre méthode sur plusieurs enregistrements lors de :
- Opérations par lots en vue arborescente
- Flux de travail automatisés
- Actions serveur
- Importations API
Si votre code suppose un seul enregistrement, il échouera.
2. Boucle manquante dans une méthode
Exemple de code problématique :
def action_confirm(self): self.state = 'confirmé'
Si self contient plusieurs enregistrements, une ambiguïté se pose.
Approche correcte :
def action_confirm(self): for record in self: record.state = 'confirmé'
3. Utilisation incorrecte de ensure_one()
Odoo fournit :
self.ensure_one()
Cela force la méthode à fonctionner avec exactement un enregistrement. Si plusieurs existent, cela déclenche délibérément l'erreur de singleton.
Utilisez cela uniquement lorsque la logique commerciale exige strictement un enregistrement (par exemple, l'ouverture d'une vue de formulaire).
4. Recherche retournant plusieurs enregistrements
Exemple :
partner = self.env['res.partner'].search([('name', '=', 'John')])
Si plusieurs enregistrements "John" existent, et que la logique ultérieure s'attend à n'en avoir qu'un seul, l'erreur apparaît.
Alternative plus sûre :
partner = self.env['res.partner'].search([('name', '=', 'John')], limit=1)
5. Ambiguïté des champs relationnels
Les erreurs impliquent souvent des relations Many2one ou One2many.
Exemple :
self.order_line.product_id.name
Si order_line contient plusieurs lignes, l'expression devient ambiguë.
Comment corriger l'erreur de Singleton attendu
Étape 1 – Boucle sur les ensembles d'enregistrements
Règle par défaut dans Odoo :
Supposer toujours que self peut contenir plusieurs enregistrements.
for record in self: record.process_logic()
Étape 2 – Utiliser limit=1 lorsque c'est approprié
Lorsqu'un seul enregistrement est logiquement valide :
enregistrement = self.env['model.name'].search(domain, limit=1)
Étape 3 – Valider les champs relationnels
Vérifiez :
- Relations Many2one
- Collections One2many
- Filtres de domaine
Assurez-vous de ne pas travailler accidentellement avec plusieurs lignes.
Étape 4 – Examiner les processus API ou d'importation
Dans des environnements fortement intégrés, les opérations en masse déclenchent souvent cette erreur car plusieurs enregistrements sont traités à la fois.
Si votre instance Odoo synchronise des données à partir de systèmes externes, assurez-vous d'une logique sécurisée pour les lots.
Comment prévenir cette erreur dans le développement futur d'Odoo
- Évitez de supposer un contexte à enregistrement unique
- Tester des méthodes sur plusieurs enregistrements sélectionnés
- Utiliser des boucles par défaut
- Ajouter limit=1 de manière consciente
- Structurer les champs relationnels de manière claire
Dans des configurations d'intégration complexes, des erreurs comme celle-ci apparaissent souvent lors d'importations automatisées ou de tâches planifiées. Concevoir des méthodes sécurisées pour les lots prévient l'instabilité.
Comment Dasolo gère les erreurs de Recordset et d'ORM
L'erreur « Singleton attendu » n'est rarement qu'une simple erreur de codage. Dans des environnements Odoo structurés, elle révèle souvent des hypothèses plus profondes sur le comportement des ensembles d'enregistrements, l'utilisation de l'ORM et la cohérence du flux de données.
Chez Dasolo, nous abordons les erreurs liées à l'ORM en examinant comment les ensembles d'enregistrements sont gérés tout au long du cycle de vie du module. Les problèmes de singleton émergent généralement lorsque la logique métier est écrite pour des enregistrements uniques mais exécutée sur des ensembles de plusieurs enregistrements, en particulier dans des flux de travail automatisés, des intégrations ou des champs calculés.
Pour prévenir les exceptions de singleton récurrentes, nous nous concentrons sur :
- Des modèles d'itération explicites sur les ensembles d'enregistrements
- L'utilisation sécurisée de ensure_one()
- Un filtrage de domaine prévisible
- Une architecture relationnelle propre
- Déclencheurs d'automatisation contrôlée
Concevoir la logique ORM en tenant compte de l'évolutivité réduit considérablement les erreurs d'exécution inattendues dans les systèmes de production.
Conclusion
L'erreur "Expected Singleton" d'Odoo est une exception ORM courante qui se produit lorsque le code tente d'opérer sur plusieurs enregistrements tout en s'attendant à n'en avoir qu'un seul. Bien que cela puisse sembler être une simple négligence de développeur, cela indique souvent des incohérences plus larges dans la gestion des ensembles d'enregistrements dans des modules personnalisés ou des processus automatisés.
En comprenant comment l'ORM d'Odoo gère les ensembles d'enregistrements et en appliquant des modèles d'itération sûrs, les développeurs peuvent empêcher cette erreur de se reproduire. Une gestion structurée des enregistrements, des validations explicites et une logique d'automatisation contrôlée sont essentielles pour maintenir des déploiements Odoo stables et prévisibles.
Lorsqu'elles sont correctement traitées, les erreurs de singleton deviennent des signaux précieux qui aident à renforcer la qualité globale du code et la fiabilité à long terme du système.
Questions fréquemment posées
Non. Elle existe dans Odoo 14, 15, 16 et 17.
Non. C'est un problème logique dans la façon dont les enregistrements sont gérés.
Non. Seulement lorsque la logique métier nécessite une exécution stricte d'un seul enregistrement.