本文介绍了PosGis和Django-Tenant的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(使用库django-tenants进行租户分隔的多租户)对于PostGis支持,文档说要添加ORIGINAL_BACKEND = "django.contrib.gis.db.backends.postgis".我有这个,但是,当我创建一个新的租户时,出现以下错误:

(Using the library django-tenants for tenant separated multi-tenancy) For PostGis support the docs say to add ORIGINAL_BACKEND = "django.contrib.gis.db.backends.postgis". I have this, however, when I go to create a new tenant I get the following error:

Traceback (most recent call last):
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\celery\app\trace.py", line 382, in trace_task
    R = retval = fun(*args, **kwargs)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\celery\app\trace.py", line 641, in __protected_call__
    return self.run(*args, **kwargs)
  File "C:\Users\Cole\Documents\GitHub\Elevate-RA-Django-App\returns_app\apps\tenant_stores\tasks.py", line 28, in create_tenant_task
    tenant.save()
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django_tenants\models.py", line 93, in save
    self.create_schema(check_if_exists=True, verbosity=verbosity)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django_tenants\models.py", line 143, in create_schema
    verbosity=verbosity)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\core\management\__init__.py", line 141, in call_command
    return command.execute(*args, **defaults)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\core\management\base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django_tenants\management\commands\migrate_schemas.py", line 63, in handle
    executor.run_migrations(tenants=tenants)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django_tenants\migration_executors\standard.py", line 15, in run_migrations
    run_migrations(self.args, self.options, self.codename, schema_name, idx=idx, count=len(tenants))
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django_tenants\migration_executors\base.py", line 34, in run_migrations
    MigrateCommand(stdout=stdout, stderr=stderr).execute(*args, **options)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\core\management\base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\core\management\commands\migrate.py", line 77, in handle
    connection.prepare_database()
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\contrib\gis\db\backends\postgis\base.py", line 26, in prepare_database
    cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\db\backends\utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\db\utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "c:\users\cole\appdata\local\programs\python\python36-32\lib\site-packages\django\db\backends\utils.py", line 83, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "spatial_ref_sys" does not exist

spatial_ref_sys表存在于我的公共架构中. django.contrib.gis应用程序在我的共享应用程序中.

The spatial_ref_sys table exists within my public schema. The django.contrib.gis app is in my shared apps.

有什么想法吗?

推荐答案

问题似乎是由默认PostGis后端引起的,特别是通过在调用我能够通过创建一个覆盖此行为的自定义数据库后端来迁移/创建模式:

The issue seems to be cause by the default PostGis backend, specifically the call to prepare the database for migration, by explicitly setting the search path prior to calling CREATE EXTENSION IF NOT EXISTS postgis I was able to migrate/create a schema by creating a custom DB backend that overrides this behaviour:

from django.contrib.gis.db.backends.postgis.base import (
    DatabaseWrapper as OriginalPostGisDatabaseWrapper,
)
from django_tenants.utils import get_public_schema_name


class DatabaseWrapper(OriginalPostGisDatabaseWrapper):
    """
    This database wrapper explicitly sets the search path when preparing the database, as
    multi-schema environments (like with Django-tenants) can cause issues with the PostGis
    backend.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.PUBLIC_SCHEMA_NAME = get_public_schema_name()

    def prepare_database(self):
        # Check that postgis extension is installed.
        with self.cursor() as cursor:
            cursor.execute('SET search_path = %s', params=[self.PUBLIC_SCHEMA_NAME])
            cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")

然后,将ORIGINAL_BACKEND设置设置为上述数据库后端的位置,而不是标准的PostGis后端.

Then, set your ORIGINAL_BACKEND setting to the location of the above DB backend instead of the standard PostGis backend.

这篇关于PosGis和Django-Tenant的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 12:16