Django
ArrayField - поле PostgreSQL
Поиск…
Синтаксис
- from django.contrib.postgres.fields импортировать ArrayField
- class ArrayField (base_field, size = None, ** options)
- FooModel.objects.filter (array_field_name__contains = [objects, to, check])
- FooModel.objects.filter (array_field_name__contained_by = [objects, to, check])
замечания
Обратите внимание, что хотя параметр size
передается PostgreSQL, PostgreSQL не будет применять его.
При использовании ArrayField
s следует помнить об этом предупреждении из документации по массивам Postgresql .
Совет. Массивы не являются наборами; поиск определенных элементов массива может быть признаком неправильной настройки базы данных. Рассмотрите возможность использования отдельной таблицы со строкой для каждого элемента, который будет элементом массива. Это будет легче искать и, скорее всего, лучше масштабируется для большого количества элементов.
Основной массив ArrayField
Чтобы создать PostgreSQL ArrayField, мы должны предоставить ArrayField тип данных, которые мы хотим сохранить в качестве поля в качестве первого аргумента. Поскольку мы будем хранить рейтинги книг, мы будем использовать FloatField
.
from django.db import models, FloatField
from django.contrib.postgres.fields import ArrayField
class Book(models.Model):
ratings = ArrayField(FloatField())
Указание максимального размера массива ArrayField
from django.db import models, IntegerField
from django.contrib.postgres.fields import ArrayField
class IceCream(models.Model):
scoops = ArrayField(IntegerField() # we'll use numbers to ID the scoops
, size=6) # our parlor only lets you have 6 scoops
Когда вы используете параметр размера, он передается postgresql, который принимает его, а затем игнорирует его! Таким образом, вполне возможно добавить 7 целых чисел в поле scoops
выше, используя консоль postgresql.
Запрос на членство в ArrayField с
Этот запрос возвращает все конусы с шоколадным ковшом и ванильным ковшом.
VANILLA, CHOCOLATE, MINT, STRAWBERRY = 1, 2, 3, 4 # constants for flavors
choco_vanilla_cones = IceCream.objects.filter(scoops__contains=[CHOCOLATE, VANILLA])
Не забудьте импортировать IceCream
модель из вашего models.py
файла.
Также имейте в виду, что django не будет создавать индекс для ArrayField
s. Если вы собираетесь их искать, вам понадобится индекс, и его нужно будет создать вручную с помощью вызова RunSQL в вашем файле миграции.
Вложенные массивы
Вы можете ArrayField
s, передав другой ArrayField
поскольку это base_field
.
from django.db import models, IntegerField
from django.contrib.postgres.fields import ArrayField
class SudokuBoard(models.Model):
numbers = ArrayField(
ArrayField(
models.IntegerField(),
size=9,
),
size=9,
)
Запрос для всех моделей, которые содержат любой элемент в списке с contains_by
Этот запрос возвращает все конусы либо соломинкой, либо ванильным ковшом.
minty_vanilla_cones = IceCream.objects.filter(scoops__contained_by=[MINT, VANILLA])