Подтвердить что ты не робот

Можно ли использовать представление базы данных в качестве модели в Django?

Я хотел бы использовать представление, которое я создал в моей базе данных в качестве источника для своего django-view.

Возможно ли это, без использования пользовательского sql?

****** 13/02/09 ОБНОВЛЕНИЕ ***********

Как и многие из предложенных ответов, вы можете просто создать свой собственный вид в базе данных, а затем использовать его в API, указав его в models.py.

какое-то предупреждение:

  • manage.py syncdb больше не будет работать
  • для просмотра нужно то же самое в начале своего имени, как и все другие модели (таблицы), например, если ваше приложение называется "вещью", тогда ваше представление нужно будет называть thing_ $viewname
4b9b3361

Ответ 1

Начиная с Django 1.1, вы можете использовать Options.managed.

Для более старых версий вы можете легко определить класс модели для представления и использовать его, как и другие ваши представления. Я просто протестировал его с помощью приложения на базе Sqlite и, похоже, работает нормально. Просто не забудьте добавить поле первичного ключа, если столбец "первичный ключ" вашего представления не имеет имени "id" и указывает имя представления в опциях "Мета", если ваше представление не называется "app_classname".

Единственная проблема заключается в том, что команда "syncdb" вызовет исключение, поскольку Django попытается создать таблицу. Вы можете предотвратить это, указав "модели просмотра" в отдельном файле Python, отличном от models.py. Таким образом, Django не увидит их при интроспекции models.py для определения моделей, создаваемых для приложения, и поэтому не будет пытаться создать таблицу.

Ответ 2

Просто обновление для тех, кто столкнутся с этим вопросом (от Google или всего остального)...

В настоящее время Django имеет простой "правильный способ" для определить модель без управления таблицами базы данных:

Options.managed

По умолчанию True, что означает, что Django создаст соответствующие таблицы базы данных в syncdb и удалит их как часть команды управления reset. То есть Django управляет жизненными циклами таблиц базы данных.

Если False, для этой модели не будут созданы операции создания или удаления таблицы базы данных. Это полезно, если модель представляет собой существующую таблицу или представление базы данных, которое было создано другими способами. Это единственное отличие, когда managed - False. Все остальные аспекты обработки модели в точности совпадают с нормальными.

Ответ 3

Я только что реализовал модель, используя представление с 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.

Ответ 4

Мы сделали это довольно широко в наших приложениях с MySQL для работы с единственным ограничением базы данных Django. Наше приложение имеет пару баз данных, работающих в одном экземпляре MySQL. Мы можем добиться, чтобы модель кросс-базы данных объединялась таким образом, пока мы создали представления для каждой таблицы в "текущей" базе данных.

Что касается вставки/обновления в представлениях, то в наших случаях использования представление в основном представляет собой "select * from [db.table];". Другими словами, мы не делаем никаких сложных объединений или фильтрации, поэтому триггер insert/updates из save() работает просто отлично. Если ваш случай использования требует таких сложных объединений или расширенной фильтрации, я подозреваю, что у вас не будет проблем с сценариями только для чтения, но может возникнуть проблема с вставкой/обновлением. Я думаю, что в MySQL есть некоторые основные ограничения, которые препятствуют обновлению представлений, которые пересекают таблицы, имеют сложные фильтры и т.д.

В любом случае, ваш пробег может измениться, если вы используете СУБД, отличную от MySQL, но Django не заботится о том, сидит ли он поверх физической таблицы или представления. Это будет РСУБД, которая определяет, действительно ли она функционирует так, как вы ожидаете. Как отметил предыдущий комментатор, вы, скорее всего, выбросите syncdb из окна, хотя мы успешно работали над ним с помощью сигнала post-syncdb, который удаляет физическую таблицу, созданную Django, и запускает нашу команду "create view...". Тем не менее, сигнал после синхронизации является немного эзотерическим в том смысле, в котором он запускается, поэтому также предостерегайте emptor.

EDIT: Конечно, "постсинхронный сигнал" означает "постсинхронный прослушиватель"

Ответ 5

Из Официальная документация Django вы можете вызвать следующее:

#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()

Надеюсь, что это поможет; -)