2017-03-08 129 views
3

我需要在django 1.10的012g的postgres支持的jsonfield上的嵌套鍵上執行values/values_list查詢。Postgres:使用Django查詢json鍵的值

class AbcModel(models.model): 
    context = fields.JSONField() 

如果有一個像值:

{ 
    'lev1': { 
    'lev': 2 
    } 
} 

我想運行一個查詢,如

AbcModel.objects.values('context__lev1__lev2').distinct() 
AbcModel.objects.values_list('context__lev1__lev2', flat=True).distinct() 

編輯:的JSON字段從django.contrib中的Django官方JSONField .postgres.fields

+1

那麼,什麼是你所面臨的問題? – karthikr

+0

django返回錯誤FieldError:無法將關鍵字'lev1'解析爲字段。不允許加入「上下文」。 – Shaumux

+0

這是數據庫中的確切json表示形式嗎? – karthikr

回答

2

於是我找到了一個解決方案,這個工程使用Django 1.10以上。 我使用KeyTransform來註釋和提取nexted鍵,並做了一個values_list。

from django.contrib.postgres.fields.jsonb import KeyTransform 
extracted_query = AbcModel.objects.annotate(lev1=KeyTransform('lev1', 'context')).annotate(lev2=KeyTransform('lev', 'lev1')) 

這個查詢允許我使用LEV1和LEV2作爲模型中的普通字段,所以我可以做一個值,values_list或領域的任何其他有效的查詢。

Django的1.11允許嵌套兩個變換的一個註釋,不知道約1.10約嵌套,因爲我已經升級到1.11

1

這並不理想,但我能夠得到t他的工作,加入了JSON字段作爲一個額外的字段,然後在額外的場主叫值:

AbcModel.objects.extra(select={ 
    "extra_field": "context->'lev1'->'lev2'" 
}).values('extra_field').distinct() 
AbcModel.objects.extra(select={ 
    "extra_field": "context->'lev1'->'lev2'" 
}).values_list('extra_field', flat=True).distinct() 
+0

如何讓' - >'運算符工作?我想用它來代替大量的'KeyTransform',但得到這個錯誤:'django.db.utils.ProgrammingError:操作符不是唯一的:未知 - >未知 LINE 1:SELECT('​​step_data' - > 'step_data' - >'workshop')AS「w」FROM「w ... ^ 提示:無法選擇最佳候選運算符,您可能需要添加明確的類型轉換。' – dirkgroten

+0

@dirkgroten KeyTransform將使用 - >如果您使用單級提取(如'step_data' - >'lev1'),並且它將使用#>運算符(如果使用嵌套或鏈接註釋來提取嵌套數據,例如'step_data' - >'lev 1' - > 'lev2' – Shaumux

+0

是的,我明白,謝謝你的回覆。但是我遇到的問題是使用顯式的'select'命令,就像你上面顯示的一樣,使用' - >'運算符顯式地引發錯誤,操作員不是唯一的)。 – dirkgroten