【问题标题】:PosGis and Django-TenantsPosGis 和 Django 租户
【发布时间】:2018-11-29 17:05:57
【问题描述】:

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

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 应用在我的共享应用中。

有什么想法吗?

【问题讨论】:

  • 似乎是cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")引起的,但是搜索路径设置为SET search_path = return_app_test,public;(其中return_app_test是我的租户架构)

标签: django postgis


【解决方案1】:

这个问题似乎是由默认 PostGis 后端引起的,特别是调用为迁移准备数据库的调用,通过在调用 CREATE EXTENSION IF NOT EXISTS postgis 之前显式设置搜索路径我能够通过创建自定义迁移/创建架构覆盖此行为的数据库后端:

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 后端。

【讨论】:

    猜你喜欢
    • 2018-06-14
    • 2015-07-08
    • 2017-05-22
    • 2016-11-19
    • 2022-10-25
    相关资源
    最近更新 更多