English 中文(简体)
我可以在Django中将数据库视图用作模型吗?
原标题:
  • 时间:2009-02-03 16:17:16
  •  标签:

我想在我的数据库中使用我创建的视图作为我的Django视图的来源。

这可行吗,不使用自定义的 SQL?

13/02/09 更新

像许多答案所建议的那样,您可以在数据库中创建自己的视图,然后通过在models.py中定义它来在API中使用。

一些警告:

  • manage.py syncdb will not work anymore
  • the view need the same thing at the start of its name as all the other models(tables) e.g if your app is called "thing" then your view will need to be called thing_$viewname
最佳回答

自从Django 1.1版以来,您可以使用Options.managed进行操作。

对于旧版应用,您可以轻松地为视图定义一个 Model 类,并像其他视图一样使用它。我刚刚在一个基于 Sqlite 的应用程序中进行了测试,它似乎可以正常工作。只需确保在您的视图的“主键”列不是名称为 id 的情况下添加一个主键字段,并且在 Meta 选项中指定视图的名称,如果您的视图不是叫做 app_classname。

唯一的问题是“syncdb”命令将引发异常,因为Django将尝试创建表。您可以通过在单独的Python文件中定义视图模型而防止这种情况发生,与models.py不同。这样,Django在审查models.py以确定为应用程序创建的模型时将不会看到它们,因此不会尝试创建表。

问题回答

这是一个更新,针对那些可能会遇到这个问题的人(来自谷歌或其他地方)...

目前,Django有一种简单的“适当方式”定义模型而无需管理数据库表格

选项.管理

默认为True,意味着Django将在syncdb中创建适当的数据库表,并在reset管理命令的一部分中删除它们。也就是说,Django管理数据库表的生命周期。

如果False,则不会为此模型执行任何数据库表创建或删除操作。如果该模型表示已存在的表或数据库视图,这将非常有用,这些表或视图已通过其他方式创建。当managedFalse时,这是唯一的差异。模型处理的所有其他方面都与正常情况完全相同。

我刚刚使用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规则。

我们在使用MySQL应用程序中大量使用了这种方法,以解决Django单个数据库限制的问题。我们的应用程序有几个数据库存在于单个MySQL实例中。只要我们为“当前”数据库中的每个表创建了视图,我们就可以通过这种方式实现跨数据库模型连接。

就插入/更新视图而言,根据我们的用例,视图基本上就是“select * from [db.table];”换言之,我们不进行复杂的连接或筛选,因此从save()触发的插入/更新操作可以正常工作。如果您的用例需要进行复杂的连接或大量的筛选,我认为您在只读情况下不会遇到任何问题,但在插入/更新操作中可能会遇到问题。我认为MySQL中存在一些潜在的约束条件,以防止您在跨表、具有复杂筛选等视图中进行更新。

无论如何,如果您使用的是MySQL之外的关系数据库管理系统,您可能会发现情况有所不同,但Django实际上并不关心它是否位于物理表或视图之上。它将是关系数据库管理系统决定它是否按您的期望运作。如之前的评论所指出的那样,您可能需要放弃syncdb,尽管我们通过一个后同步信号成功地解决了这个问题,该信号会删除Django创建的物理表并运行我们的“create view…”命令。但是,后同步信号在触发时有一个有点特别的方式,所以请注意风险。

当然,“post-syncdb signal”指的是“post-syncdb listener”。

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

希望能帮到您;-)





相关问题
热门标签