Django访问多个PostgreSQL Schema

在我们的博客中, 记录了我们在开发过程中所使用的技术和遇到的问题, 希望作为其他开发和设计者的一个学习交流平台.

Django访问多个PostgreSQL Schema


django缺少对PostgreSQL的多schema支持, 之前我们尝试了多种方法访问除public schema之外的schemas, 但这些方式都难以维护.

然而, 最近我们发现这一问题可以使用PostgreSQL的search_path参数轻松地解决.

一个简单的例子

假设一个django项目中所有的表都创建在django schema中, 并且我们的项目需要用到legacy schema中几个表. 我们可以通过PostgreSQL数据库映射, 然后在django中使用DATABASE设置实现, 让我们展示一下其他两种不同的设置方法:

在连接时设置search_path

假设django和legacy schema已经存在, 且django项目具有数据库的访问权.

在django设置中, 我们在options中设置search_path:

    # settings.py
    DATABASES = {

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

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

这一设置方式对于已有的项目而言需要修改的地方最少.

设置不同的数据库用户

对于以上设置而言, 最大的问题可能是set search_path参数在每次django项目与PostgreSQL数据库进行连接时都需要传输.

为了节约这一时间, 我们可以事先为每个用户设定search_path:

用postgres用户登入psql shell:

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

    -- user accessing legacy schema...
    CREATE USER legacy_user LOGIN PASSWORD 'secret';
    GRANT appuser TO legacy_user;
    ALTER ROLE legacy_user SET search_path TO legacy, public;

django项目中settings.py:

    DATABASES = {

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

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

以上便是两种不同的使用search_path的方式.

自定义django database router也许也能做到自动选择正确的schema.


原文链接: http://weiguda.com/blog/58/