從這個問題繼:Django Postgresql ArrayField aggregationDjango的Postgres的ArrayField聚合和過濾
我有分類的ArrayField
,我想找回它擁有所有的獨特的價值觀 - 但是結果應進行篩選,以便只值與開始提供的字符串被返回。
什麼是「最Django」的做法?
給定一個Animal
模型,看起來像這樣:
class Animal(models.Model):
# ...
categories = ArrayField(
models.CharField(max_length=255, blank=True),
default=list,
)
# ...
然後,按照the other question's answer,這適用於尋找所有類別,過濾。
all_categories = (
Animal.objects
.annotate(categories_element=Func(F('categories'), function='unnest'))
.values_list('categories_element', flat=True)
.distinct()
)
不過,現在,當我嘗試過濾結果我得到的失敗,不僅僅是__startswith
但所有類型的filter
:
all_categories.filter(categories_element__startswith('ga'))
all_categories.filter(categories_element='dog')
堆棧跟蹤的底部是:
DataError: malformed array literal: "dog"
...
DETAIL: Array value must start with "{" or dimension information.
...看起來,這是因爲Django試圖做第二個UNNEST
- 這是它產生的SQL:
...) WHERE unnest("animal"."categories") = dog::text[]
如果我寫在PSQL查詢則似乎需要一個子查詢爲UNNEST
的結果:
SELECT categories_element
FROM (
SELECT UNNEST(animal.categories) as categories_element
) ul
WHERE ul.categories_element like 'Ga%';
有沒有辦法讓Django的ORM,使工作查詢?或者我應該放棄ORM並使用原始SQL?
也許可以使用https://docs.djangoproject.com/en/1.9/ref/models/querysets/#extra得到子查詢在那裏。 'annotate'似乎有些錯誤(通常用於聚合類型函數) – Anentropic
Thanks @Antropic - 我確實看過'extra',但看不到添加子查詢的方法。下面的答案可能是「最真實」的 - 模式並不適合真正的目的。我已經實現了一個迷你查詢構建器,可以從ArrayFields中進行選擇和排序,並且看起來很好地工作。 – jamesc
我想知道你是否可以把子查詢放在'tables'參數中 – Anentropic