Django 和 postgresql 模式

标签 django postgresql schema database-schema

我整个星期都在努力解决这个问题,非常感谢您的帮助。

我在 postgres 数据库中有各种模式,我希望能够从相同或不同的 Django 应用程序映射到它们。

一些模式是:

样本

挖掘

地球物理学

...

我已经尝试了推荐的方法,但我没有从模式中获取任何数据来显示,我只能连接到具有托管表的公共(public)模式。这是来自 settings.py 文件的数据库连接。

DATABASES = {

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

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

来源:https://www.amvtek.com/blog/posts/2014/Jun/13/accessing-multiple-postgres-schemas-from-django/

在 model.py 中我添加:

    from django.db import models

    # Create your models here.
    class Storage(models.Model):
        #id = models.IntegerField(default=0)
        storage_id = models.AutoField(primary_key=True)
        store_name = models.CharField(max_length=200, default='')
        address_1 = models.CharField(max_length=200, default='')
        address_2 = models.CharField(max_length=200, default='')
        region = models.CharField(max_length=200, default='')
        city = models.CharField(max_length=200, default='')
        zip = models.CharField(max_length=200, default='')
        country = models.CharField(max_length=200, default="Turkey")
        user = models.CharField(max_length=200, default="Gygaia")
        datestamp = models.DateTimeField(auto_now=True)

    class Meta():
        managed=False
        db_table = 'samples\".\"store'

我不想将架构限制在用户范围内,而且数据库是几年前创建的,所以我不允许将其全部置于一个架构下。我知道在 stackoverflow 和互联网的其他 coreners 上发布了各种解决方案,我已经尝试过这些,但我无法让它工作。有什么解决办法吗??

最佳答案

因为 Django 不支持开箱即用的 Postgres 数据库模式,为了让它工作,使用 database router .

我创建了一个测试数据库来尝试这个,这里是重现它的方法:

用psql创建一个测试数据库:

CREATE USER tester WITH PASSWORD 'lol so easy';
CREATE DATABASE multi_schema_db WITH OWNER tester;
CREATE SCHEMA samples AUTHORIZATION tester;
CREATE TABLE samples.my_samples (
  id          INTEGER   NOT NULL PRIMARY KEY,
  description CHAR(255) NOT NULL
);

将模式作为不同的数据库连接添加到设置中,记得添加 HOST 以避免“Peer authentication failed”错误。

DATABASES = {

'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'OPTIONS': {
        'options': '-c search_path=django,public'
    },
    'NAME': 'multi_schema_db',
    'USER': 'tester',
    'PASSWORD': 'lol so easy',
    'HOST': 'localhost'

},

'samples': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'OPTIONS': {
        'options': '-c search_path=samples,public'
    },
    'NAME': 'multi_schema_db',
    'USER': 'tester',
    'PASSWORD': 'lol so easy',
    'HOST': 'localhost'
},

接下来创建 MySample 模型:

from django.db import models

class MySample(models.Model):
    description = models.CharField(max_length=255, null=False)

    class Meta:
        managed = False
        db_table = 'my_samples'

创建一个数据库路由器,将所有与示例相关的查询定向到示例数据库:

from database_test.models import MySample

ROUTED_MODELS = [MySample]


class MyDBRouter(object):

    def db_for_read(self, model, **hints):
        if model in ROUTED_MODELS:
            return 'samples'
        return None

    def db_for_write(self, model, **hints):
        if model in ROUTED_MODELS:
            return 'samples'
        return None

基本上,路由器会将 ROUTED_MODELS 中指定的所有模型路由到数据库连接 samples 并为所有其他模型返回 None。这会将它们路由到 default 数据库连接。

最后将路由器添加到你的settings.py

DATABASE_ROUTERS = ('database_test.db_router.MyDBRouter',)

现在,当对 MySample 模型进行查询时,它将从 samples 模式中获取数据。

关于Django 和 postgresql 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50819748/

相关文章:

python - 我在 Django 应用程序中的同一类的两个对象之间存在 OneToOne 关系。是否有可能加强这种关系的唯一性?

python - 如何跟踪 Python/Django/uwsgi/nginx 超时

json - 在 postgres 中选择或提取 jsonb 数据内的所有键值

schema - 为分析平台设计 GraphQL 模式

django - 如何在 Django 表单中使用 TimeInput 小部件?

javascript - 用 Javascript/jQuery 构建计时器

ruby-on-rails - Postgres 不会使用 c9.io 连接到 Ruby on Rails 应用程序中的服务器

SQL:重用函数返回的值?

mysql - 如果其中一个字段已经是唯一的,我可以添加一个复合唯一键吗

javascript - 是的验证消息