【问题标题】:Django and postgresql schemasDjango 和 postgresql 模式
【发布时间】:2018-11-22 00:05:23
【问题描述】:

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

我在 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


    【解决方案1】:

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

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

    【讨论】:

    • 今天必须实现一个数据库路由器,所以可以回到这里检查我自己的答案。谢谢你,圣诞节过去的我。
    • 我只是想添加一些您需要使用python manage.py migrate --database <db-config-name> <app-name> 的内容,以便将迁移应用到正确的数据库。我还必须为路由器类实现allow_migrateallow_relation 方法,不确定是否是所有情况。 docs.djangoproject.com/en/3.1/topics/db/multi-db/… 了解更多信息。
    【解决方案2】:

    我也咨询了那个来源,但我不能像你一样解决它,但通过执行测试我实现了以下。

    如果我们有例如模式 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 中管理变量。限制是我们必须自己命名表。

    【讨论】:

      猜你喜欢
      • 2015-09-29
      • 2017-05-18
      • 2019-07-12
      • 2016-10-05
      • 2012-11-08
      • 1970-01-01
      • 1970-01-01
      • 2017-11-14
      • 1970-01-01
      相关资源
      最近更新 更多