Django 和 postgresql 架构

问题描述 投票:0回答:4

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

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

一些模式是:

样品

挖掘

地球物理学

...

我已经尝试了推荐的方法,但我没有从模式中显示任何数据,我只能使用托管表连接到公共模式。这是来自 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 和互联网的其他核心上发布了各种解决方案,我已经尝试过这些,但我无法让它发挥作用。有什么想法可以解决这个问题吗??

django postgresql schema database-schema
4个回答
63
投票

因为 Django 不支持开箱即用的 Postgres 数据库架构,为了使其正常工作,请使用 数据库路由器

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

使用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
以避免“对等身份验证失败”错误。

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
模式中获取数据。


16
投票

我也查阅了该来源,但我无法像你一样解决它,但通过执行测试我实现了以下目标。

例如,如果我们有模式 foo 和 bar,在 Meta 中写入:

class MySample1 (models.Model):
     description = models.CharField (max_length = 255, null = False)
     class Goal:
         managed = True
         db_table = 'fo\".\"my_samples1'

class MySample2 (models.Model):
     description = models.CharField (max_length = 255, null = False)
     class Goal:
         managed = True
         db_table = 'bar\".\"my_samples2'

然后我们可以将每个模型重定向到我们想要的方案,前提是我们在 True 中管理了变量。限制是我们必须自己命名表。


0
投票

首先使用模式在postgres中创建表,然后在django中访问这些表 使用命令 python manage.pyspectdb > models.py 然后迁移回来。


0
投票

search_path
是这里的关键。这是一个 Postgres 设置,决定在尝试查找匹配表时如何遍历数据库(source)。

您不需要定义多个路由器或显式指定db_table或类似的内容,除非您在多个模式中具有相同名称的表,您应该避免这样做,因为它简化了此过程。

因此,为了使您的 PostgreSQL 连接在访问数据库时始终能够遍历您想要的所有模式,您只需要永久修改其

search_path

source
): ALTER DATABASE <database_name> SET search_path TO schema1,schema2; -- After running this command, you will have to close your current connection and -- reconnect for the changes to be reflected in your session

然后,您将能够像往常一样仅定义 
default

Django

DATABASES
设置,它将查看所有给定的模式以找到适当的表。
    

© www.soinside.com 2019 - 2024. All rights reserved.