Могу ли я использовать представление базы данных в качестве модели в Django?
-
21-08-2019 - |
Вопрос
я хотел бы использовать представление, которое я создал в своей базе данных, в качестве источника для моего представления django.
Возможно ли это без использования специального sql?
******ОБНОВЛЕНИЕ 13.02.09************
Как следует из многих ответов, вы можете просто создать свое собственное представление в базе данных, а затем использовать его в API, определив его в models.py.
хотя бы небольшое предупреждение:
- syncdb Manage.py больше не будет работать
- в начале имени представления требуется то же самое, что и для всех других моделей (таблиц), например, если ваше приложение называется «thing», тогда ваше представление должно будет называтьсяthing_$viewname
Решение
Начиная с Django 1.1, вы можете использовать Опции.управляемые для этого.
В более старых версиях вы можете легко определить класс модели для представления и использовать его так же, как и другие представления.Я только что протестировал его с помощью приложения на базе Sqlite, и, похоже, оно работает нормально.Просто обязательно добавьте поле первичного ключа, если столбец «первичного ключа» вашего представления не имеет имени «id», и укажите имя представления в мета-параметрах, если ваше представление не называется «имя_класса приложения».
Единственная проблема заключается в том, что команда «syncdb» вызовет исключение, поскольку Django попытается создать таблицу.Вы можете предотвратить это, определив «модели представления» в отдельном файле Python, отличном от models.py.Таким образом, Django не увидит их при анализе файла models.py для определения моделей, которые необходимо создать для приложения, и поэтому не будет пытаться создать таблицу.
Другие советы
Просто обновление для тех, кто столкнется с этим вопросом (от Google или чего-то еще)...
В настоящее время у Django есть простой «правильный способ» определить модель без управления таблицами базы данных:
Опции.управляемые
По умолчанию
True
, то есть Django создаст соответствующие таблицы базы данных вsyncdb
и удалите их как частьreset
команда управления.то есть Джанго управляет жизненные циклы таблиц базы данных.Если
False
, для этой модели не будут выполняться операции создания или удаления таблиц базы данных.Это полезно, если модель представляет собой существующую таблицу или представление базы данных, созданное каким-либо другим способом.Это только разница, когдаmanaged
являетсяFalse
.Все остальные аспекты обработки модели такие же, как обычно.
Я только что реализовал модель, используя представление с помощью postgres 9.4 и django 1.8.
Я создал собственные классы миграции следующим образом:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_previousdependency'),
]
sql = """
create VIEW myapp_myview as
select your view here
"""
operations = [
migrations.RunSQL("drop view if exists myapp_myview;"),
migrations.RunSQL(sql)
]
Я написал модель, как обычно.Это работает для моих целей.
Примечание— Когда я запустил makemigrations, для модели был создан новый файл миграции, который я удалил вручную.
Полное раскрытие информации: мое представление доступно только для чтения, поскольку я использую представление, полученное из типа данных jsonb, и не написал правило ON UPDATE INSTEAD.
Мы довольно часто делали это в наших приложениях с MySQL, чтобы обойти ограничение Django, связанное с единственной базой данных.В нашем приложении есть несколько баз данных, находящихся в одном экземпляре MySQL.Таким образом мы можем добиться объединения моделей между базами данных, если мы создали представления для каждой таблицы в «текущей» базе данных.
Что касается вставок/обновлений в представления, то в наших случаях представление представляет собой, по сути, «выбрать * из [db.table];».Другими словами, мы не выполняем каких-либо сложных объединений или фильтрации, поэтому триггер вставки/обновления из save() работает нормально.Если ваш вариант использования требует таких сложных объединений или обширной фильтрации, я подозреваю, что у вас не возникнет никаких проблем для сценариев только для чтения, но могут возникнуть проблемы с вставкой/обновлением.Я думаю, что в MySQL есть некоторые основные ограничения, которые не позволяют вам обновлять представления, которые пересекают таблицы, имеют сложные фильтры и т. д.
В любом случае, ваш опыт может отличаться, если вы используете СУБД, отличную от MySQL, но Django не заботится о том, находится ли она поверх физической таблицы или представления.Именно СУБД будет определять, действительно ли она работает так, как вы ожидаете.Как заметил предыдущий комментатор, вы, скорее всего, выбросите syncdb в окно, хотя мы успешно обошли это с помощью сигнала post-syncdb, который удаляет физическую таблицу, созданную Django, и запускает нашу команду «создать представление...».Однако сигнал post-syncdb немного эзотеричен в том, как он запускается, так что и здесь будьте осторожны.
РЕДАКТИРОВАТЬ:Конечно, под «сигналом post-syncdb» я имею в виду «прослушиватель post-syncdb».
От Официальная документация Джанго, вы можете вызвать представление следующим образом:
#import library
from django.db import connection
#Create the cursor
cursor = connection.cursor()
#Write the SQL code
sql_string = 'SELECT * FROM myview'
#Execute the SQL
cursor.execute(sql_string)
result = cursor.fetchall()
Надеюсь, поможет ;-)