Django:查询没有主键的只读视图

Posted

技术标签:

【中文标题】Django:查询没有主键的只读视图【英文标题】:Django: Querying read-only view with no primary key 【发布时间】:2009-03-03 10:36:46 【问题描述】:
class dbview(models.Model):
    # field definitions omitted for brevity
    class Meta:
        db_table = 'read_only_view'

def main(request):
    result = dbview.objects.all()

渲染时遇到异常:(1054, "Unknown column 'read_only_view.id' in 'field list'")

我可以在视图中看到没有主键。有解决办法吗?

评论: 我无法控制使用 Django 访问的视图。 mysql 浏览器在那里显示列,但没有主键。

【问题讨论】:

【参考方案1】:

当您说“我无法控制使用 Django 访问的视图时。 MySQL 浏览器在那里显示列,但没有主键。'

我假设您的意思是这是一个旧表,并且不允许您添加或更改列?

如果是这样并且确实没有主键(甚至是字符串或非 int 列*),那么表设置得不是很好,性能可能很糟糕。

不过,这对你来说并不重要。您所需要的只是保证每一行都是唯一的列。在您的模型中将其设置为 'primary_key = True,Django 会很高兴。

还有另一种可能存在问题的可能性。如果没有保证唯一的列,则该表可能正在使用复合主键。也就是说 - 它指定将两列放在一起将提供一个唯一的主键。这是完全有效的关系建模,但不幸的是 Django 不支持。在这种情况下,除了原始 SQL 之外,您将无能为力,除非您可以添加另一列。

【讨论】:

非常感谢,这真的很有帮助! 非常有帮助。要补充的一件事;如果要用作主键的列是 CHAR 类型,则不能超过 255 个字符。 这并没有真正解决与数据库视图有关的问题,而不是表。您已将其中一个字段指定为 django 的 pk,无论是否。您可以摆脱这一点,因为永远不会通过 ORM 对关系进行任何插入/更新。有关此技术的更多信息,请参阅the answer from David S 和我的评论。【参考方案2】:

我一直有这个问题。我有一个不能或不想更改的视图,但我希望有一个页面来显示复合信息(可能在管理部分)。我只是覆盖保存并引发 NotImplementedError:

    def save(self, **kwargs):
        raise NotImplementedError()

(虽然这在大多数情况下可能不需要,但它让我感觉好一点)

我还在 Meta 类中将 managed 设置为 False。

    class Meta:
       managed = False

然后我只需选择任何字段并将其标记为主键。它是否真的很独特并不重要,您只是在做过滤器以在页面上显示信息等。

对我来说似乎工作得很好。如果我忽略的这种技术有任何问题,请发表评论。

【讨论】:

您可以将非唯一字段标记为只读访问的主键,但这会对queryset.distinct().count() 和实例比较等内容产生影响。作为后者的解决方法,您可以在模型上重新定义__eq__() 如果您想拥有一个 id,您可以对视图执行的操作是使用 row_number() 函数(至少在 PostgreSQL 中)。 SELECT row_number() OVER (ORDER BY field ASC) AS id,【参考方案3】:

如果视图中确实没有主键,那么就没有变通方法。

Django requires each model to have exactly one field primary_key=True.

【讨论】:

谢谢!如果我在视图中看不到主键,这意味着没有主键......?我想我会恢复到原始 SQL。 不一定。请参阅下面的评论。【参考方案4】:

当你运行 syncdb 时应该有一个自动生成的 id 字段(如果你的模型中没有定义主键,那么 Django 会为你插入一个 AutoField)。

这个错误意味着 Django 正在向您的数据库询问 id 字段,但不存在。你能运行django manage.py dbshell 然后DESCRIBE read_only_view; 并发布结果吗?这将显示数据库中的所有列。

或者,您可以包含您排除的模型定义吗? (并确认您在运行 syncdb 后没有更改模型定义?)

【讨论】:

谢谢,我应该在一开始就说得更清楚。请查看更新。 我不是要查看您正在访问的行,我只是想查看您的模型定义(不是同一件事)。 模型定义是这样的: text = models.CharField() 但是,我不能用 'primary_key=True' 定义一个字段,因为视图似乎没有主键。 不好意思说得这么直白,但是你知道主键是什么吗? 我看问题的方式:视图没有主键(我看不到),Django要求每个模型都有一个主键(要么手动定义'primary_key=True ' 或默认的 'id' 如果用户未定义)。

以上是关于Django:查询没有主键的只读视图的主要内容,如果未能解决你的问题,请参考以下文章

Yii——关于无主键的数据表或视图

oracle:物化视图中的主键列

没有主键的桥接表

如果没有主键,如何在 Django 中建模数据库视图?

Oracle序列索引视图分页

如何在 Oracle 视图上添加主键? [复制]