betagouv / recommandations-collaboratives

Outil support Recommandations-Collaboratives basé sur le framework django
https://recommandations-collaboratives.beta.gouv.fr
GNU Affero General Public License v3.0
8 stars 10 forks source link

Erreur lors du lancement de l'application (no such table: django_site) #611

Open bastien-rcc opened 3 months ago

bastien-rcc commented 3 months ago

Décrivez le bug Lors du lancement de l'applicatif l'erreur suivante apparaît :

django.db.utils.OperationalError: no such table: django_site

Comment le reproduire ? Les étapes pour reproduire ce bug: En suivant les instructions du README, aussi bien via virtualenv que via docker.

Via virtualenv j'ai laissé la configuration avec sqlite pour ne pas installer PostgreSQL et j'obtiens cette erreur.

Via docker j'ai laissé la configuration de sqlite pour tester si le résultat était le même et c'est bien le cas. J'ai ensuite mis à jour la configuration de DATABASES dans recoco/settings/development.py telle qu'indiquée dans le README et j'ai vérifié que les variables d'environnement sont bien bien présentes dans le container. Puis en lançant ./manage.py migrate une erreur similaire apparaît : django.db.utils.ProgrammingError: relation "django_site" does not exist

Ce bug semble commun mais aucune des solutions proposées dans des cas similaires ne fonctionne ici.

Le stack trace depuis le container :

root ➜ /workspace $ ./manage.py migrate
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
psycopg.errors.UndefinedTable: relation "django_site" does not exist
LINE 1: ..."django_site"."domain", "django_site"."name" FROM "django_si...
                                                             ^

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/workspace/./manage.py", line 22, in <module>
    main()
  File "/workspace/./manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 106, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 100, in handle
    self.check(databases=[database])
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 485, in check
    all_issues = checks.run_checks(
                 ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/checks/registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/checks/urls.py", line 42, in check_url_namespaces_unique
    all_namespaces = _load_all_namespaces(resolver)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/checks/urls.py", line 61, in _load_all_namespaces
    url_patterns = getattr(resolver, "url_patterns", [])
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/urls/resolvers.py", line 715, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                       ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/urls/resolvers.py", line 708, in urlconf_module
    return import_module(self.urlconf_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/workspace/recoco/urls.py", line 17, in <module>
    from wagtail.admin import urls as wagtailadmin_urls
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/urls/__init__.py", line 143, in <module>
    path(f"sprite-{get_sprite_hash()}/", home.sprite, name="wagtailadmin_sprite"),
                   ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/urls/__init__.py", line 133, in get_sprite_hash
    content = str(home.sprite(None).content, "utf-8")
                  ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/views/home.py", line 381, in sprite
    return HttpResponse(icons())
                        ^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/views/home.py", line 367, in icons
    render_to_string(icon)
  File "/usr/local/lib/python3.11/site-packages/django/template/loader.py", line 61, in render_to_string
    template = get_template(template_name, using=using)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/template/loader.py", line 15, in get_template
    return engine.get_template(template_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/template/backends/django.py", line 33, in get_template
    return Template(self.engine.get_template(template_name), self)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/template/engine.py", line 175, in get_template
    template, origin = self.find_template(template_name)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/template/engine.py", line 157, in find_template
    template = loader.get_template(name, skip=skip)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/template/loaders/base.py", line 23, in get_template
    contents = self.get_contents(origin)
               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/dbtemplates/loader.py", line 30, in get_contents
    content, _ = self._load_template_source(origin.template_name)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/dbtemplates/loader.py", line 53, in _load_template_source
    site = Site.objects.get_current()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/contrib/sites/models.py", line 59, in get_current
    return self._get_site_by_id(site_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/multisite/hacks.py", line 44, in SiteManager_get_site_by_id
    site = self.get(pk=site_id)
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 633, in get
    num = len(clone)
          ^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 380, in __len__
    self._fetch_all()
  File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 1881, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 91, in __iter__
    results = compiler.execute_sql(
              ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1562, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 102, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
    raise ex.with_traceback(None)
django.db.utils.ProgrammingError: relation "django_site" does not exist
LINE 1: ..."django_site"."domain", "django_site"."name" FROM "django_si...
                                                             ^

Comportement normal attendu Le lancement complet de l'applicatif.

Votre environnement

glibersat commented 3 months ago

Salut @bastien-rcc , sqlite n'est pas supporté, on utilise des extensions propres à pG. C'est possible que ça vienne de là !

freesteph commented 1 month ago

Bonjour à tous, je me suis aussi cassé les dents sur ce problème qui intervient à cause des URLs Wagtail qui s'immiscent dans le lancement de l'application avant que les migrations n'aient pu être effectuées (dont celles nécessaires pour l'utilisation de multisite).

Pour y remédier je n'ai trouvé qu'une solution assez triste :

modified   recoco/urls.py
@@ -13,9 +13,9 @@ from django.contrib import admin
 from django.contrib.auth import views as auth_views
 from django.urls import include, path
 from magicauth.urls import urlpatterns as magicauth_urls
-from wagtail import urls as wagtail_urls
-from wagtail.admin import urls as wagtailadmin_urls
-from wagtail.documents import urls as wagtaildocs_urls
+# from wagtail import urls as wagtail_urls
+# from wagtail.admin import urls as wagtailadmin_urls
+# from wagtail.documents import urls as wagtaildocs_urls

 from recoco.apps.addressbook.urls import urlpatterns as addressbook_urls
 from recoco.apps.crm.urls import urlpatterns as crm_urls
@@ -36,9 +36,9 @@ urlpatterns = [
     path("hijack/", include("hijack.urls")),
     path("nimda/", admin.site.urls),
     path("cookies/", include("cookie_consent.urls")),
-    path("cms/", include(wagtailadmin_urls)),
-    path("documents/", include(wagtaildocs_urls)),
-    path("p/", include(wagtail_urls)),
+    # path("cms/", include(wagtailadmin_urls)),
+    # path("documents/", include(wagtaildocs_urls)),
+    # path("p/", include(wagtail_urls)),
 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 urlpatterns.extend(magicauth_urls)

après quoi on peut bien migrer la base :

docker compose -f docker/docker-compose.yml run --rm web python manage.py migrate

puis décommenter les lignes précédentes et relancer l'application sans problèmes. Je ne connais pas assez Wagtail pour allez plus loin, @glibersat tu sais s'il est possible de différer les lignes problématiques ?

glibersat commented 1 month ago

Hello @freesteph , yes, merci du retour. En effet, on a wagtail qui sollicite très tôt les sites, sauf que comme on utilise multisites, qui lui se lie à la BDD, ça la démarre trop tôt et impossible de bootstraper sans modifier ce que tu as fait.

C'est dans ma TODO pour essayer de patcher le bootstrap initial, mais toujours pas fait ^^ On peut, à minima, documenter la bidouille pour éviter à chacun de se galérer à l'installation cela dit, ça ne serait pas du luxe.