如何从 Django QuerySet 获取字段名称,即使它是一个空集?

问题描述 投票:0回答:1

Django 和 Pandas 之间的一个很酷的结合是能够直接从

DataFrame
构建一个
QuerySet
使用:

queryset = models.A.objects.filter(...).annotate(...)
frame = pd.DataFrame(queryset.values())

只要

QuerySet
至少返回一条记录,这就非常有效。 在
QuerySet
级别执行操作很有趣,因为在那里我们可以享受所有注释和本机列的好处。

但是这个方法将返回一个完全空的

DataFrame
(没有定义列),比方说:

queryset = models.A.objects.filter(id__lt=0).annotate(...)
frame = pd.DataFrame(queryset.values())

DataFrame 完全是空的:

Empty DataFrame
Columns: []
Index: []

虽然我们想要这样的东西:

Empty DataFrame
Columns: ["id", "key", "prop1", ...]
Index: []

为了让这个框架能够与另一个框架无缝合并,保留列名的地方。

pandas 的方法是使用

DataFrame
开关在
columns
创建时强制列名。

queryset = models.A.objects.filter(...)
frame = pd.DataFrame(queryset.values(), columns=queryset.get_fields())

不幸的是,对于

get_fields
对象,这个
QuerySet
或类似的乍一看似乎没有实现或显而易见。

我已经知道我可以使用这个脏的

QuerySet
exists()
中获取列名:

frame = pd.DataFrame(
    queryset.values(),
    columns=queryset[0].__dict__.keys()
)

但是,它确实不适用于空的

QuerySet
.

我也知道我可以获得如下模型列:

frame = pd.DataFrame(
    queryset.values(),
    columns=[item.name for item in queryset.model._meta.get_fields()] + [...]
)

但是我会错过

QuerySet
创建的所有注释列,或者需要手动对其进行编码,这是我们想要避免的。

我觉得

QuerySet
可能知道它应该返回的所有列。至少它应该在查询执行后知道它,因为空的 SQL 结果集肯定会包含列名和类型。

所以我的问题是:How to get fields name from Django QuerySet, even when it's an empty set?

如果结构有点奇怪或令人费解,这不是问题,只要它也允许获取注释列名称。

python django pandas django-queryset
1个回答
0
投票

我认为您已经探索了从 Django 获取字段名称的所有可能选项。您必须记住,

Queryset
本身不是模型字段的表示,而不是数据库中的数据。因此,您将从模型类或模型(对象)的实例而不是查询集中获取模型字段。因此,最简单的方法是定义您想要获取的字段,然后在将其传递给 Pandas DataFrame 之前将其用于
queryset.values()
的值查询集。像这样:

# you are annotating the fields, hence you already know the names of the fields
fields = [item.name for item in queryset.model._meta.get_fields()] + [...]
frame = pd.DataFrame(
    queryset.values(*fields),
    columns=fields
)
© www.soinside.com 2019 - 2024. All rights reserved.