Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django Postgresql JsonField查询相关字典键_Python_Django_Postgresql_Django Jsonfield_Postgresql Json - Fatal编程技术网

Python Django Postgresql JsonField查询相关字典键

Python Django Postgresql JsonField查询相关字典键,python,django,postgresql,django-jsonfield,postgresql-json,Python,Django,Postgresql,Django Jsonfield,Postgresql Json,我拥有的模型的一部分使用Django模型字段,如下所示: class SalesModel(models.Model): some_data = models.PositiveIntegerField(db_index=True) some_other_data = models.CharField(max_length=50) json_data = JSONField(blank=True, null=True) 下面是JsonData字段的格式: [{"id":

我拥有的模型的一部分使用Django模型字段,如下所示:

class SalesModel(models.Model):
    some_data = models.PositiveIntegerField(db_index=True)
    some_other_data = models.CharField(max_length=50)
    json_data = JSONField(blank=True, null=True)
下面是JsonData字段的格式:

[{"id": val, "contribution": "some_val", }, {"id": some_val, "contribution": "some_other_val",}, {"id": other_val, "contribution": "some_another_val"}]
i、 例如,格式为:

 [{'id':XX, 'contribution':XX},{'id':YY, 'contribution':YY},{'id':ZZ, 'contribution':ZZ}]
目前,我可以使用ID的val筛选Django表。现在,我想知道该特定ID的贡献

例如,如果val=1,我想过滤模型SalesModel,它包含id=1的JsonField,我想显示相关的贡献。因此,这意味着,在3个可能的字典中(根据字段构造),我只显示一个字典(通过该字典的“ID”键过滤)。这意味着,如果第二个字典具有匹配的ID,则仅显示第二个贡献,如果第一个ID匹配,则仅显示第一个贡献,对于第三个字典也是如此


有办法吗?

是的,我想。如果我理解正确,您将有一个要匹配的id或一个id列表。因此,如果您的ID为2:

my_id = 2
dict1 = [{"id":1, "contribution":10},{"id":2, "contribution":20},{"id":3, "contribution":30}] 
for i in dict1:
    if i["id"] == my_id:
        print(i["contribution"])
这应该行得通


您可以以不同的方式重新构造
JSONField
,方法是给它一个dict,其中键、值对是
id:contribution
。通过这种方式,您可以使用
has_key
过滤器和
KeyTransform
将起作用,因为我不确定它在dict数组上是否起作用。因此,假设您的
json_数据
如下所示:

{1: 'xx', 3: 'yy', 9: 'zz'}
您可以通过这种方式根据贡献进行查询:

SalesModel.filter(json_data__has_key=id)\
    .annotate(contrib=KeyTransform(id, 'json_data')\
    .values('contrib')
或者,在postgresql中使用原始jsonb:

SalesModel.filter(json_data__has_key=id)\
    .extra(select={'contrib': "json_data->{0}".format(id)})\
    .values('contrib')

好的,我将有大约100K的数据,平均约20K的数据。我不希望运行for循环。虽然循环是一种选择,但我们是否可以使用ORM/Raw SQL进行处理?谢谢你花了这么多时间。你会看到我们有3个循环。如果更频繁地达到100K标记,则不太好。您确定我们可以将“值”与特定于“postgresql”的“jsonfield”一起使用吗。让我试试。但据我所知,这可能是一个错误。。它应该是django.core.exceptions.FieldError:无法将关键字“贡献”解析到字段中。在“json_数据”上加入不是permitted@dirkgroten确切地说,这就是我所认为的错误,因为Django不允许这样做,而且我不知道Postgres允许使用任何原始SQL,但我认为它应该工作。。。看一看似乎完全相同的问题。如果它起作用,我会把它标记为重复的。这听起来不错。KeyTransform似乎没有太多官方文档。无论哪种方式,您都可以确认KeyTransform在django 1.10.X级别(X=5)上工作。什么是键转换呢?很抱歉在评论中问了一个愚蠢的问题。如果不好的话,让我用谷歌搜索并理解。不,我不能确认这在Django 1.10.x上有效,我使用的是1.11。但是
KeyTransform
在1.10.x上是受支持的,所以我很确定它可以工作。请注意,嵌套的
KeyTransform
s(在本例中不需要)仅在Django 1.11.x及更高版本中受支持。
KeyTransform
keytextransforms
等。。。通过组合json文档的两个键并添加相应的。所以
contrib=KeyTransform('key','json_data')
基本上是选择json_data::json->'key'。谢谢@dirkgroten。。。这似乎是一个完整的解决方案
SalesModel.filter(json_data__has_key=id)\
    .extra(select={'contrib': "json_data->{0}".format(id)})\
    .values('contrib')