Django and postgresql schemas



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

我在 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 不支持开箱即用的 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架构中获取数据。

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

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

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

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

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

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

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

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

然后,您将能够像往常一样仅定义defaultDjangoDATABASES设置,它将查看所有给定的模式以找到合适的表。

但是请注意,您可能仍需要使用db_table在除schema1以外的任何内容中创建新表

最新更新