使用Django 1.11与Sql-Server数据库视图的问题

时间:2018-04-13 15:36:09

标签: django sql-server-2012 django-1.11 django-pyodbc database-view

我正在尝试使用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至关重要...

1 个答案:

答案 0 :(得分:1)

我想通了 - 我有一个自定义的数据库路由器(在settings.DATABASE_ROUTERS中)我没有正确添加到这里(我这样做是因为项目有多个数据库 - 请参阅Multi-DB以了解原因和这该怎么做)。 (我这样的笨蛋)

但这就是我发现的:如果你的项目中有1个数据库,那么我使用的所有三种方法都应该可行。如果您有多个数据库,那么您可以通过模型对象(例如,<Model Name>.objects.all())或通过原始sql查询数据库,但是您必须通过模型指定原始sql(例如,<Model Name>.objects.raw(<select * from <view name>)) - 否则您的数据库路由器将不知道要使用哪个数据库。