Проблемы с использованием Django 1.11 с представлением базы данных Sql-Server

Я пытаюсь использовать Django (django 1.11.4) для чтения данных из представления SQL-Server (sql server 2012 — для этого я использую sql_server.pyodbc [он же django-pyodbc]), и ничего не работает.

Вот моя модель:

class NumUsersAddedPerWeek(models.Model):

    id = models.BigIntegerField(primary_key=True)
    year = models.IntegerField('Year')
    week = models.IntegerField('Week')
    num_added = models.IntegerField('Number of Users Added')

    if not settings.RUNNING_UNITTESTS:
        class Meta:
            managed = False
            db_table = 'num_users_added_per_week'

и вот как создается представление базы данных:

create view num_users_added_per_week
as

    select row_number() over(order by datepart(year, created_at), datepart(week, created_at)) as 'id',
datepart(year, created_at) as 'year', datepart(week, created_at) as 'week', count(*) as 'num_added'
    from [<database name>].[dbo].[<table name>] 
    where status = 'active' and created_at is not null
    group by datepart(year, created_at), datepart(week, created_at)

Представление прекрасно работает само по себе (например, запуск select * from num_users_added_per_week выполняется нормально (и очень быстро)...

Я использовал следующую команду django (т. е. «действие»), чтобы попробовать 3 разных способа получения данных через модель, и ни один из них не сработал (хотя, судя по другим сообщениям, эти подходы, похоже, работали с предыдущими версиями django ) :(:

from django.core.management.base import BaseCommand, CommandError
from <project name>.models import NumUsersAddedPerWeek
from django.db import connection

class Command(BaseCommand):

    def handle(self, *args, **options):

        # attempt # 1 ...
        num_users_info = NumUsersAddedPerWeek.objects.all()
        info = num_users_info.first()
        for info in num_users_info:
            print(info)

        # attempt # 2 ...
        cursor = connection.cursor()
        cursor.execute('select * from num_users_added_per_week')
        result = cursor.fetchall()

        # attempt # 3 ...
        num_users_info = NumUsersAddedPerWeek.objects.raw('select * from num_users_added_per_week')
        for info in num_users_info:
            print(info)

Каждый из трех разных подходов дает мне одну и ту же ошибку: "('42S02', "[42S02] [Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Недопустимое имя объекта "num_users_added_per_week". (208) (SQLExecDirectW)"). "

Обратите внимание: мои миграции работают нормально - добавление class Meta: managed = False имеет решающее значение в последних версиях Django в ситуациях, когда вы не хотите, чтобы миграции создавали/обновляли/удаляли структуру вашей таблицы sql...


person karlk    schedule 13.04.2018    source источник
comment
Вы создали представление с помощью миграции в Django? Если вы создали его непосредственно в SSMS, вы уверены, что создали его с тем же пользователем, с которым Django подключается к базе данных?   -  person FlipperPA    schedule 13.04.2018


Ответы (1)


Я понял это - у меня есть собственный маршрутизатор базы данных (в settings.DATABASE_ROUTERS), к которому я не добавил это должным образом (я делаю это, потому что проект имеет несколько баз данных - см. Multi-DB, чтобы узнать, почему и как это сделать). (Так что глупая ошибка с моей стороны)

Но вот что я выяснил: Оказывается, все три использованных мной метода должны работать, если у вас в проекте 1 база данных. Если у вас есть несколько баз данных, вы можете запросить базу данных через объект вашей модели (например, <Model Name>.objects.all()) или через необработанный sql, но вы должны указать необработанный sql через свою модель (например, <Model Name>.objects.raw(<select * from <view name>)) - в противном случае ваш маршрутизатор базы данных не будет знать, какой базу данных для использования.

person karlk    schedule 13.04.2018