J'ai essayé de résoudre celui-ci toute la semaine, aide très appréciée.
J'ai plusieurs schémas dans une base de données postgres et j'aimerais pouvoir les mapper depuis la même application ou entre différentes applications Django.
Certains des schémas sont:
des échantillons
les fouilles
géophysique
...
J'ai essayé la méthode recommandée, mais je ne reçois aucune donnée à afficher à partir des schémas, je ne peux me connecter qu'au schéma public avec des tables gérées. Voici les connexions à la base de données à partir du fichier 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',
},
}
source: https://www.amvtek.com/blog/posts/2014/Jun/13/accessing-multiple-postgres-schemas-from-Django/
Dans le model.py j'ajoute:
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'
Je ne veux pas restreindre les schémas aux utilisateurs, et la base de données a été créée il y a quelques années. Je ne suis donc pas autorisée à la regrouper sous un seul schéma. Je sais qu'il existe diverses solutions publiées sur stackoverflow et sur d'autres sources d'Internet. J'ai déjà essayé ces solutions, mais je ne parviens pas à faire en sorte que cela fonctionne. Des idées comment résoudre cela?
Dans la mesure où Django ne prend pas en charge les schémas de base de données Postgres prêts à l'emploi, utilisez un routeur database .
J'ai créé une base de données de test pour essayer ceci, voici comment la reproduire:
Créez une base de données de test avec 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
);
Ajoutez les schémas aux paramètres en tant que connexions à la base de données différentes. N'oubliez pas d'ajouter Host
pour éviter l'erreur «L'authentification par l'homologue a échoué».
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'
},
}
Créez ensuite le modèle 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'
Créez un routeur de base de données pour diriger toutes les requêtes relatives aux exemples vers la base de données exemple:
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
Fondamentalement, le routeur acheminera tous les modèles spécifiés dans ROUTED_MODELS vers la connexion à la base de données samples
et renverra Aucun pour tous les autres modèles. Cela les acheminera vers la connexion à la base de données default
.
Enfin, ajoutez le routeur à votre settings.py
DATABASE_ROUTERS = ('database_test.db_router.MyDBRouter',)
Et maintenant, lorsque vous effectuez une requête pour le modèle MySample
, il va extraire les données du schéma samples
.
J'ai aussi consulté cette source, mais je ne pouvais pas la résoudre comme vous, mais en effectuant des tests, j'ai obtenu les résultats suivants.
Si nous avons par exemple, les schémas foo et bar, écrivant dans le 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'
Ensuite, nous pouvons rediriger chaque modèle vers le schéma souhaité, à condition que la variable soit gérée dans True. La limitation est que nous devons nommer la table nous-mêmes.