Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
310 views
in Technique[技术] by (71.8m points)

postgis - PosGis and Django-Tenants

(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:userscoleappdatalocalprogramspythonpython36-32libsite-packagesceleryapp	race.py", line 382, in trace_task
    R = retval = fun(*args, **kwargs)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesceleryapp	race.py", line 641, in __protected_call__
    return self.run(*args, **kwargs)
  File "C:UsersColeDocumentsGitHubElevate-RA-Django-App
eturns_appapps	enant_stores	asks.py", line 28, in create_tenant_task
    tenant.save()
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjango_tenantsmodels.py", line 93, in save
    self.create_schema(check_if_exists=True, verbosity=verbosity)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjango_tenantsmodels.py", line 143, in create_schema
    verbosity=verbosity)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangocoremanagement\__init__.py", line 141, in call_command
    return command.execute(*args, **defaults)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangocoremanagementase.py", line 335, in execute
    output = self.handle(*args, **options)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjango_tenantsmanagementcommandsmigrate_schemas.py", line 63, in handle
    executor.run_migrations(tenants=tenants)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjango_tenantsmigration_executorsstandard.py", line 15, in run_migrations
    run_migrations(self.args, self.options, self.codename, schema_name, idx=idx, count=len(tenants))
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjango_tenantsmigration_executorsase.py", line 34, in run_migrations
    MigrateCommand(stdout=stdout, stderr=stderr).execute(*args, **options)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangocoremanagementase.py", line 335, in execute
    output = self.handle(*args, **options)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangocoremanagementcommandsmigrate.py", line 77, in handle
    connection.prepare_database()
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangocontribgisdbackendspostgisase.py", line 26, in prepare_database
    cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangodbackendsutils.py", line 100, in execute
    return super().execute(sql, params)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangodbackendsutils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangodbackendsutils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangodbackendsutils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangodbutils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "c:userscoleappdatalocalprogramspythonpython36-32libsite-packagesdjangodbackendsutils.py", line 83, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "spatial_ref_sys" does not exist

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

Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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")

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...