我正在尝试使用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命令(即'action')尝试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 ) “)”
请注意:我的迁移运行正常 - 在您不希望迁移创建/更新/删除sql表结构的情况下,添加class Meta: managed = False
对于最新版本的Django至关重要...
答案 0 :(得分:1)
我想通了 - 我有一个自定义的数据库路由器(在settings.DATABASE_ROUTERS中)我没有正确添加到这里(我这样做是因为项目有多个数据库 - 请参阅Multi-DB以了解原因和这该怎么做)。 (我这样的笨蛋)
但这就是我发现的:如果你的项目中有1个数据库,那么我使用的所有三种方法都应该可行。如果您有多个数据库,那么您可以通过模型对象(例如,<Model Name>.objects.all()
)或通过原始sql查询数据库,但是您必须通过模型指定原始sql(例如,<Model Name>.objects.raw(<select * from <view name>)
) - 否则您的数据库路由器将不知道要使用哪个数据库。