Projet

Général

Profil

Development #36028

traces en rapport à des notifs, "current database router prevents this relation."

Ajouté par Frédéric Péters il y a plus de 4 ans. Mis à jour il y a plus de 4 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
11 septembre 2019
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

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

Révision 1dca5156 (diff)
Ajouté par Emmanuel Cazenave il y a plus de 4 ans

prevent inconsistent use of db alias (#36028)

Historique

#1

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.
#2

Mis à jour par Emmanuel Cazenave il y a plus de 4 ans

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.

#3

Mis à jour par Emmanuel Cazenave il y a plus de 4 ans

  • Privée changé de Oui à Non
#4

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

#5

Mis à jour par Emmanuel Cazenave il y a plus de 4 ans

Yes beaucoup mieux (il fallait juste utiliser db_manager au lieu de using sur ContentType.objects). Et un test.

#6

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
#7

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)
#8

Mis à jour par Emmanuel Cazenave il y a plus de 4 ans

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF