2016-07-25 6 views
3

Я пытаюсь выяснить способ запроса данных внутри postgres JSONField в конкретном экземпляре моей модели.Запросить содержимое JSONField модели Django

Из всего, что я видел, все варианты использования эквивалентны, если у вас есть атрибуты JSONField, а затем выбирая все экземпляры вашей модели, где атрибуты - >> color = 'red' или что-то еще.

Так давайте дадим это более реальный пример, скажем, у нас есть модель Shoe и имеет цену и количество, и все, как поля, но затем также JSONField под названием versions, который представляет собой массив объектов, каждый из которых объекты, имеющие вещи, которые делают каждую версию особенной.

Так что, если один экземпляр модели обуви Air Jordans, атрибуты JSONField может выглядеть следующим образом:

[ 
    { 
     color: black, 
     edition: limited, 
     tongueColor: red 
    }, 
    { 
     color: black, 
     edition: standard 
    }, 
    { 
     color: gold, 
     edition: fancy, 
     bright: very 
    } 
] 

Таким образом, есть две вещи, которые мы можем сделать, мы можем:

  1. Запрос модели для всех туфель, которые имеют доступную версию с цветом: черный (который вернет наши Air Jordans, плюс, возможно, другие туфли), или
  2. Запросить экземпляр модели для всех объектов внутри версий JSONField, где цвет = черный. Итак, если у нас уже было Shoe.objects.filter(name='Air Jordans') или что-то в этом роде, можно было бы применить какой-то метод или что-то в конце, чтобы просто вернуть первые два объекта выше, где color == black?

Я могу найти примеры в Интернете, сделав первый, но не второй.

Я мог бы просто принести объект в память и отфильтровать оттуда, но этот JSONField - это то место, где я надеялся хранить очень большие количества произвольных данных, и поэтому возможность запроса без привлечения целого блоба в память довольно важна , Может ли JSONField поддерживать это?

+0

Как вы знаете, мы можем сделать вторую вещь? – valignatev

+1

Я не совсем уверен, но я думаю, что вы можете сделать что-то вроде этого. .filter (versions__contains = {'color': 'black'}) 'или' .filter (versions__contains = [{'color': 'black'} ]) '. В противном случае вам, вероятно, следует создать некоторый пользовательский поиск и использовать 'json_to_recordset()' https://www.postgresql.org/docs/9.5/static/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE –

+0

@valentjedi - у меня есть не знаю, возможно ли это, очень возможно, что это не так. – cbrainerd

ответ

1

@AntoinePinsard указал мне в правильном направлении - json_to_recordset().

настоящее время я использую что-то вроде:

SELECT * FROM (
    SELECT j.* from shoes, json_to_recordset(json_field_name) as 
    j(color text, edition text, tongueColor: text, bright text) where 
    shoes.shoe_name = 'Air Jordan' 
) subset 
WHERE subset.color= "black" 

Так внутренний оператор выбора будет строить внутренне набор записей, который выглядит следующим образом:

 
color | edition | tongueColor | bright 
------+----------+-------------+-------- 
black | limited | red   | 
black | standard |    | 
gold | fancy |    | very 

и затем внешний оператор запрашивает, что внутренний (в этом случае, когда цвет = «черный» и возвращается:

 
color | edition | tongueColor | bright 
------+----------+-------------+-------- 
black | limited | red   | 
black | standard |    | 

Спасибо за помощь всем!

+0

Вы могли работать с этим решением в ORM Django? – skulk001

1

Это может работать для вас:

Shoes.objects.filter(yourJsonFieldName__contains={'colors': 'black'}) 
Смежные вопросы