Проблемы с использованием Django 1.11 с представлением базы данных Sql-Server
Я пытаюсь использовать Django (django 1.11.4) для чтения данных из представления SQL-Server (sql server 2012 - я использую sql_server.pyodbc [aka 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)
Каждый из 3-х разных подходов дает мне одну и ту же ошибку: "('42S02', "[42S02] [Microsoft][Драйвер ODBC SQL Server][SQL Server] Недопустимое имя объекта 'num_users_added_per_week'. (208) (SQLExecDirectW)")"
Пожалуйста, обратите внимание: мои миграции выполняются просто отлично - добавление class Meta: managed = False
имеет решающее значение с последними версиями Django в ситуациях, когда вы не хотите, чтобы миграции создавали / обновляли / удаляли структуру таблицы SQL...
1 ответ
Я понял это - у меня есть собственный Маршрутизатор базы данных (в settings.DATABASE_ROUTERS), к которому я не добавил это должным образом (я делаю это, потому что у проекта есть несколько баз данных - см. Multi-DB, чтобы узнать, почему и как это сделать), (Так багатик с моей стороны)
Но вот что я обнаружил: оказывается, все три метода, которые я использовал, должны работать, если у вас есть 1 база данных в вашем проекте. Если у вас есть несколько баз данных, вы можете запросить базу данных через объект вашей модели (например, <Model Name>.objects.all()
) или через raw sql, но вы должны указать необработанный sql через вашу модель (например, <Model Name>.objects.raw(<select * from <view name>)
) - иначе ваш Database Router не будет знать, какую базу данных использовать.