如何从Django连接到多个PostgreSQL模式?

13

在我的GeoDjango项目中,我想连接到一个传统的PostgreSQL/PostGIS数据库。它包含以下模式:

  • data // 包含所有的地理空间数据
  • django // 空的,由我创建
  • public // 系统表,如 spatial_ref_sys

我希望 Django 表格(如截图所示)进入 django 模式。我不想污染 public 模式。

Django tables

我希望 "data" 模型连接到 data 模式。我已经尝试使用从旧表生成模型,但是 python manage.py inspectdb 连接到 public 模式。


为了提供对不同模式的访问,我采用了这篇文章的第2种方法,将个人的 search_path 值预分配给特定的数据库用户:

-- user accessing django schema...
CREATE ROLE django_user LOGIN PASSWORD 'secret';
ALTER ROLE django_user SET search_path TO django, public;

-- user accessing data schema...
CREATE ROLE data_user LOGIN PASSWORD 'secret';
ALTER ROLE data_user SET search_path TO data, public;

然后我按以下方式配置了数据库连接:

DATABASES = {

    'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'multi_schema_db',
            'USER': 'django_user',
            'PASSWORD': 'secret',
    },

    'data': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'multi_schema_db',
            'USER': 'data_user',
            'PASSWORD': 'secret',
    },
}

我该如何配置Django使用django模式,同时"data" 模型连接到data 模式?


阅读材料


请查看自动数据库路由器 - falsetru
@falsetru,自动数据库路由器的文档没有提到如何处理一个数据库中的多个模式。 - JJD
@JJD 你找到这个问题的答案了吗?谢谢! - Abz Rockers
@AbzRockers 只有你可以在这里阅读的内容(https://dev59.com/K1wZ5IYBdhLWcg3wM9_Z#39322184)。 - JJD
1
@JJD 谢谢您的回复!如果它解决了您的问题,我认为您应该将其标记为正确答案。我忽略了这个问题的答案,因为它没有标记正确答案,也没有赞同。 - Abz Rockers
3个回答

10

你需要利用 search_path

DATABASES = {

    'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'OPTIONS' : {
                'options': '-c search_path=django,public'
            },
            'NAME': 'multi_schema_db',
            'USER': 'django_user',
            'PASSWORD': 'secret',
    },

    'data': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'OPTIONS' : {
                'options': '-c search_path=data,public'
            },
            'NAME': 'multi_schema_db',
            'USER': 'data_user',
            'PASSWORD': 'secret',
    },
}

7
如果您不需要通过迁移来管理表格,您可以在模型的db_table属性中使用转义引号
class SomeModel(models.Model):
    field1 = models.AutoField(primary_key=True)  
    class Meta():
        managed=False
        db_table=u'"schema\".\"table"'

这对我有用。 您也可以简单地使用未转义的引号。 db_table='schema"."table' - Mathuv
这太棒了,据我所知,它也可以与迁移一起使用! - ladorm
对我来说,无论是带引号还是不带引号都没有起作用。 - Ladenkov Vladislav
在没有设置managed=False并且仅在数据库中创建模式之前运行任何迁移的情况下,它对我起作用了。 - sɪʒɪhɪŋ βɪstɦa kxɐll

2
我们使用Django租户模式取得了很好的效果。它允许您通过将不同的租户作为模式所有者来访问不同的模式。
这将允许您基于每个调用设置模式。如果需要在每个URL基础上设置模式,则可以在中间件中执行此操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接