Проблема: я хочу использовать схемы Postgres для разделения таблиц разных частей моего приложения django на уровне базы данных.
В сторону
Вы можете пропустить этот раздел, но я думаю, что полезно добавить контекст к этим вещам. Мое приложение работает с базой данных существующих данных (полезно хранящихся в схеме public
), которые очень важно не изменять. Таким образом, я хочу разделить «мои» данные в отдельную схему (к которой django будет предоставлен доступ для чтения/записи/воспроизведения в песке), ограничивая доступ к схеме public
только для чтения. Первоначально я пытался решить эту проблему, выделив свои данные в отдельную базу данных и используя маршрутизацию базы данных, но оказалось (если бы я только прочитал документацию), что django не поддерживает зависимости между базами данных (что достаточно справедливо, я полагаю ), и мои модели имеют внешние ключи в данных только для чтения.
Мясо
Существует обходной путь для отсутствия поддержки схемы в Django (о котором вы можете прочитать здесь), который заключается в укажите атрибут db_table
в метаданных вашей модели, например:
class MyModel(models.Model):
attribute1 = models.CharField()
#Fool django into using the schema
class Meta:
db_table = 'schema_name\".\"table_name'
Это здорово, но я действительно не хотел писать это для каждой отдельной модели в моем приложении - для начала это не кажется питоническим, а также есть все шансы, что я забуду, когда мне нужно добавить новый модель.
Моим решением был следующий фрагмент:
def SchemaBasedModel(cls):
class Meta:
db_table = '%s\".\"%s' % (schema_name, cls.__name__)
cls.Meta = Meta
return cls
@SchemaBasedModel
class MyModel(models.Model):
attribute1 = models.CharField()
...
Когда я запускаю python manage.py shell
, я получаю следующее:
>>> from myapp import models
>>> myModel = models.MyModel
>>> myModel.Meta.db_table
'myschema"."mymodel'
>>>
«Выглядит хорошо для меня», — подумал я. Затем я побежал: python manage.py sqlall myapp
. К сожалению, это дало исходные имена таблиц, то есть имена таблиц, какими они были до того, как я применил эту метаинформацию. Когда я вернулся и применил метаинформацию «вручную» (то есть, добавив Meta
внутренних классов ко всем моим моделям), все было так, как и ожидалось (новые имена таблиц).
Я надеялся, что кто-нибудь может просветить меня относительно того, что здесь происходит? Или, что более полезно, как это сделать "правильно"? Я думал, что шаблон декоратора, о котором я здесь говорил, будет как раз билетом для этой проблемы, но, по-видимому, это не начало. Как я могу быстро и легко применить эту метаинформацию ко всем своим моделям, не вводя ее каждый раз?
Редактировать: возможно, я был немного неясен, когда спрашивал об этом — мне также интересно знать, что «на самом деле происходит» (т. Я неправильно понимаю здесь?) как решить мою проблему (четкое разделение "моих" данных от устаревших данных, желательно на уровне схемы - но это не конец света, если я должен свалить все в схему public
и управлять разрешениями в расчете на стол).
Второе редактирование: принятый ответ не обязательно говорит мне то, что я действительно хочу знать, но он является, вероятно, правильным решением для реальной проблемы. Краткий ответ: не делайте этого.