Development #36028
traces en rapport à des notifs, "current database router prevents this relation."
0%
Description
Traceback (most recent call last): File "/usr/bin/docbow-ctl", line 11, in <module> execute_from_command_line(sys.argv) File "/usr/lib/python2.7/dist-packages/django/core/management/__init__.py", line 354, in execute_from_command_line utility.execute() File "/usr/lib/python2.7/dist-packages/django/core/management/__init__.py", line 346, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/usr/lib/python2.7/dist-packages/django/core/management/base.py", line 394, in run_from_argv self.execute(*args, **cmd_options) File "/usr/lib/python2.7/dist-packages/django/core/management/base.py", line 445, in execute output = self.handle(*args, **options) File "/usr/lib/python2.7/dist-packages/django/utils/decorators.py", line 145, in inner return func(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/docbow_project/docbow/management/commands/notify.py", line 12, in handle notification.process_notifications() File "/usr/lib/python2.7/dist-packages/docbow_project/docbow/notification.py", line 176, in process_notifications notifier=notifier.__class__) File "/usr/lib/python2.7/dist-packages/django_journal/journal.py", line 74, in error_record return record(tag, tpl, **kwargs) File "/usr/lib/python2.7/dist-packages/django/utils/decorators.py", line 145, in inner return func(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/django_journal/journal.py", line 58, in record journal.objectdata_set.create(tag=tag, content_object=value) File "/usr/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 756, in create return super(RelatedManager, self.db_manager(db)).create(**kwargs) File "/usr/lib/python2.7/dist-packages/django/db/models/manager.py", line 127, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 346, in create obj = self.model(**kwargs) File "/usr/lib/python2.7/dist-packages/django/db/models/base.py", line 468, in __init__ setattr(self, field.name, rel_obj) File "/usr/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 649, in __set__ raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value) ValueError: Cannot assign "<ContentType: notification>": the current database router prevents this relation.
Fichiers
Révisions associées
Historique
Mis à jour par Emmanuel Cazenave il y a plus de 4 ans
- Projet changé de Parlement Wallon à Django Journal
C'est la fonction django_journal/journal.py::error_record qui plante (et stop net tout le traitement des notifications dans docbow au lieu de passer à la suivante).
Elle peut recevoir en argument n'importe quel objet dont des instances de django.db.models.Model. Ceux-ci sont marqués comme appartenant à une base de donnée, en pratique ici un objet appartenant à la DB désignée par 'défaut' dans la configuration.
Et dans error_record un hack pour effectuer quelques écritures sur la même base mais désignée sous un autre nom (ici 'journal' parce que JOURNAL_DB_FOR_ERROR_ALIAS='journal'), pour ne pas être pris dans la transaction courante.
def error_record(tag, tpl, **kwargs): '''Records error events. You must use this function when logging error events. It uses another database alias than the default one to be immune to transaction rollback when logging in the middle of a transaction which is going to rollback. ''' if kwargs.get('using') is None: kwargs['using'] = getattr(settings, 'JOURNAL_DB_FOR_ERROR_ALIAS', 'default')
Et donc quelques lignes plus loin, on essaie d'établir une relation entre l'objet reçu dans la fonction et un objet créé après le hack :
if isinstance(value, django.db.models.Model): journal.objectdata_set.create(tag=tag, content_object=value) (Pdb) value._state.db 'default' (Pdb) journal._state.db 'journal'
Et donc logiquement django pas d'accord :
ValueError: Cannot assign "<ContentType: notification>": the current database router prevents this relation.
Mis à jour par Emmanuel Cazenave il y a plus de 4 ans
- Fichier 0001-prevent-inconsistent-use-of-db-alias-36028.patch 0001-prevent-inconsistent-use-of-db-alias-36028.patch ajouté
- Statut changé de Nouveau à Solution proposée
- Patch proposed changé de Non à Oui
Après le hack pour ne pas être pris dans la transaction, le hack pour défaire le premier hack si les circonstances l'exigent.
Pas le courage d'écrire le test unitaire (et sur l'idée qu'on pourrait plutôt se débarrasser de django-journal), mais testé en vrai.
Mis à jour par Benjamin Dauvergne il y a plus de 4 ans
- Statut changé de Solution proposée à En cours
Par défaut GenericForeignKey.__set__() va chercher le ContentType dans la même db que l'objet posé et pas celui de l'objet créé1.
Pour passer outre faire :
journal.objectdata_set.create(tag=tag, content_type=ContentType.objects.using(using).get_for_model(value), object_id=value.pk)
Ça devrait marcher dans toutes les situations.
1 Voir https://github.com/django/django/blob/1.11.24/django/contrib/contenttypes/fields.py#L268 et
https://github.com/django/django/blob/1.11.24/django/contrib/contenttypes/fields.py#L162
Mis à jour par Emmanuel Cazenave il y a plus de 4 ans
- Fichier 0001-prevent-inconsistent-use-of-db-alias-36028.patch 0001-prevent-inconsistent-use-of-db-alias-36028.patch ajouté
- Statut changé de En cours à Solution proposée
Yes beaucoup mieux (il fallait juste utiliser db_manager au lieu de using sur ContentType.objects). Et un test.
Mis à jour par Benjamin Dauvergne il y a plus de 4 ans
- Statut changé de Solution proposée à Solution validée
- Assigné à mis à Emmanuel Cazenave
Mis à jour par Emmanuel Cazenave il y a plus de 4 ans
- Statut changé de Solution validée à Résolu (à déployer)
ommit 1dca515624f3b9e4c8a6727c011a8d2c6fa5ae54 Author: Emmanuel Cazenave <ecazenave@entrouvert.com> Date: Wed Sep 11 18:22:07 2019 +0200 prevent inconsistent use of db alias (#36028)
Mis à jour par Emmanuel Cazenave il y a plus de 4 ans
- Statut changé de Résolu (à déployer) à Solution déployée
prevent inconsistent use of db alias (#36028)