Скажем, у меня есть Postgres DB с schema1
и schema2
.Я бы хотел, чтобы мое приложение Django myapp
получало доступ к данным как schema1
, так и schema2
.
. Я почти нашел решение, использующее app_labels
(на основе этот ответ )До тех пор, пока я не понял, что это сломало администратора Django, и, следовательно, возможно, другие функции.
Я пытался указать пользовательский app_label
в моделях Meta
:
class OneModel(models.Model):
gid = models.AutoField(primary_key=True)
name = models.CharField(max_length=40, blank=True, null=True)
class Meta:
managed = False
db_table = 'one_table'
app_label = 'myapp_to_schema1'
class AnotherModel(models.Model):
gid = models.AutoField(primary_key=True)
color = models.CharField(max_length=40, blank=True, null=True)
class Meta:
managed = False
db_table = 'another_table'
app_label = 'myapp_to_schema2'
Затем я реализую два отдельных маршрутизатора для myapp, каждый из которых направляет одну из схем:
class MyappToSchema1Router:
def db_for_read(self, model, **hints):
if model._meta.app_label == 'myapp_to_schema1':
return 'schema1'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'myapp_to_schema1':
return 'schema1'
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'myapp_to_schema1':
return db == 'schema1'
return None
class MyappToSchema2Router:
def db_for_read(self, model, **hints):
if model._meta.app_label == 'myapp_to_schema2':
return 'schema2'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'myapp_to_schema2':
return 'schema2'
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'myapp_to_schema2':
return db == 'schema2'
return None
Наконец, БД настроены следующим образом:
DATABASES = {
'default':
{
},
'schema1':
{
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'OPTIONS': {
'options': '-c search_path=schema1'
},
'NAME': 'mydb',
'USER': secrets.USER,
'PASSWORD': secrets.PASSWORD,
'HOST': 'my.host.address',
'PORT': '5432',
},
'schema2':
{
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'OPTIONS': {
'options': '-c search_path=schema2'
},
'NAME': 'mydb',
'USER': secrets.USER,
'PASSWORD': secrets.PASSWORD,
'HOST': 'my.host.address',
'PORT': '5432',
},
}
}
Как уже упоминалось, это работаетхорошо (т.е. я могу получить доступ к обеим моделям в оболочке Python, используя, например, OneModel.objects.all()
и AnotherModel.objects.all()
), но при посещении администратора Django я получаю сообщение об ошибке No installed app with label 'myapp_to_schema1'.
Каков будет правильный способполучить доступ к нескольким схемам из одного приложения?