如何从Django连接到多个PostgreSQL架构?

时间:2015-07-30 14:09:07

标签: django postgresql database-schema postgis geodjango

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

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

我希望屏幕截图中显示的Django表进入django架构。我不想污染public架构。

Django tables

我想要"数据"模型连接到data架构。我已尝试generate models from the legacy tables,但python manage.py inspectdb已连接到public架构。

为了提供对不同模式的访问,我调整了approach 2 of this article,它将单个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架构,而#34;数据"模型连接到data架构?

读数

3 个答案:

答案 0 :(得分:5)

您必须利用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',
    },
}

答案 1 :(得分:1)

我们使用Django Tenant Schemas取得了巨大成功。它允许您通过将不同的租户描述为模式的所有者来访问不同的模式。

这将允许您基于每个呼叫设置架构。如果需要基于每个url设置架构,则可以在中间件中执行此操作。

答案 2 :(得分:1)

如果您不需要通过迁移管理表格,则可以使用转义引号作为模型的db_table属性:

class SomeModel(models.Model):
    field1 = models.AutoField(primary_key=True)  
    class Meta():
        managed=False
        db_table=u'"schema\".\"table"'