如何从 postgresql 视图表中获取要显示的对象列表

Posted

技术标签:

【中文标题】如何从 postgresql 视图表中获取要显示的对象列表【英文标题】:How can i get a list of objects from a postgresql view table to display 【发布时间】:2010-12-12 11:05:15 【问题描述】:

这是视图表的模型。

class QryDescChar(models.Model): 
 iid_id = models.IntegerField()
 cid_id = models.IntegerField()
 cs = models.CharField(max_length=10)
 cid = models.IntegerField()
 charname = models.CharField(max_length=50)
 class Meta:
     db_table = u'qry_desc_char'

这是我用来创建表的 SQL

CREATE VIEW qry_desc_char as
 SELECT  
    tbl_desc.iid_id,
    tbl_desc.cid_id,
    tbl_desc.cs,
    tbl_char.cid,
    tbl_char.charname
FROM tbl_desC,tbl_char 
WHERE tbl_desc.cid_id = tbl_char.cid;

我不知道我是否需要模型或视图中的功能或两者兼而有之。我想从该数据库中获取对象列表以显示它。这可能很容易,但我是 Django 和 python 的新手,所以我遇到了一些问题

【问题讨论】:

【参考方案1】:

您正在尝试从视图中获取记录。这是不正确的,因为视图不映射到模型,表映射到模型。

您应该使用 Django ORM 来获取 QryDescChar 对象。请注意,Django ORM 将直接从表中获取它们。您可以查阅 Django 文档以了解 extra()select_related() 方法,这将允许您以不同的方式获取相关数据(您想从另一个表中获取的数据)。

【讨论】:

【参考方案2】:

如果您的 RDBMS 允许您创建可写视图,并且您创建的视图具有与 Django 创建的表完全相同的结构,我想这应该可以直接工作。

【讨论】:

【参考方案3】:

Django 1.1 引入了一个您可能会觉得有用的新功能。您应该能够执行以下操作:

 class QryDescChar(models.Model): 
     iid_id = models.IntegerField()
     cid_id = models.IntegerField()
     cs = models.CharField(max_length=10)
     cid = models.IntegerField()
     charname = models.CharField(max_length=50)
 class Meta:
     db_table = u'qry_desc_char'
     managed = False

托管元类选项的文档是here。相关引述:

如果为 False,则不创建数据库表 或删除操作将 为此模型执行。这是 如果模型代表一个 现有表或数据库视图 是通过其他方式创建的。 这是唯一的区别 管理为 False。的所有其他方面 模型处理与 正常。

完成后,您应该可以正常使用您的模型了。要获取对象列表,您可以执行以下操作:

qry_desc_char_list = QryDescChar.objects.all()

要真正将列表放入模板中,您可能需要查看通用视图,特别是 object_list 视图。

【讨论】:

【参考方案4】:

(这是一个古老的问题,但仍然是一个令人困惑的领域,并且仍然与使用预先存在的规范化模式的 Django 的任何人高度相关。)

在您的 SELECT 语句中,您需要添加一个数字“id”,因为 Django 需要一个,即使在非托管模型上也是如此。如果某处的行上没有保证唯一的整数值,您可以使用 row_number() 窗口函数来完成此操作(对于视图,这通常是这种情况)。

在这种情况下,我在窗口函数中使用了 ORDER BY 子句,但是您可以执行任何有效的操作,并且当您使用它时,您还可以使用对您有用的子句。只要确保你不要尝试使用 Django ORM 点引用来引用关系,因为它们会默认查找“id”列,而你的是假的。

此外,如果您要在对象中使用它,我会考虑将输出列重命名为更有意义的名称。有了这些更改,查询看起来更像(当然,用您自己的术语替换“AS”子句):

CREATE VIEW qry_desc_char as
 SELECT
    row_number() OVER (ORDER BY tbl_char.cid) AS id,
    tbl_desc.iid_id AS iid_id,
    tbl_desc.cid_id AS cid_id,
    tbl_desc.cs AS a_better_name,
    tbl_char.cid AS something_descriptive,
    tbl_char.charname AS name
FROM tbl_desc,tbl_char 
WHERE tbl_desc.cid_id = tbl_char.cid;

完成后,在 Django 中,您的模型可能如下所示:

class QryDescChar(models.Model):
    iid_id = models.ForeignKey('WhateverIidIs', related_name='+',
                                db_column='iid_id', on_delete=models.DO_NOTHING)
    cid_id = models.ForeignKey('WhateverCidIs', related_name='+',
                                db_column='cid_id', on_delete=models.DO_NOTHING)
    a_better_name = models.CharField(max_length=10)
    something_descriptive = models.IntegerField()
    name = models.CharField(max_length=50)

    class Meta:
        managed = False
        db_table = 'qry_desc_char'

您不需要在 id 列名称末尾添加“_id”部分,因为您可以像我上面所做的那样使用“db_column”参数在 Django 模型上使用更具描述性的方式声明列名称(但在这里我只是为了防止 Django 在 cid_id 和 iid_id 的末尾添加 another "_id" - 这为您的代码添加了零语义值)。另外,请注意“on_delete”参数。当涉及到级联删除时,Django 会做自己的事情,而在一个有趣的数据模型上你不希望这样做——当涉及到视图时,你只会得到一个错误和一个中止的事务。在 Django 1.5 之前,您必须对其进行修补以使 DO_NOTHING 实际上意味着“什么都不做”——否则它仍然会尝试(不必要地)在执行删除周期之前查询并收集所有相关对象,并且查询将失败,停止整个操作。

顺便说一句,I wrote an in-depth explanation of how to do this 只是前几天。

【讨论】:

以上是关于如何从 postgresql 视图表中获取要显示的对象列表的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL查看表表索引视图表结构以及参数设置

SQL 如何查询指定架构中所有表(或视图)的名称

如何从持久存储中获取数据并显示在自定义表格视单元上?有没有示例代码?

如何保留使用多个连接的密钥?

从视图表中获取数据时出现 Laravel 错误

文本文件字符串拆分然后将每个元素输出到视图表中