Django
ArrayField - un champ spécifique à PostgreSQL
Recherche…
Syntaxe
- à partir de django.contrib.postgres.fields importer ArrayField
- class ArrayField (base_field, size = None, ** options)
- FooModel.objects.filter (array_field_name__contains = [objets, à, cocher])
- FooModel.objects.filter (array_field_name__contained_by = [objets, à, cocher])
Remarques
Notez que même si le paramètre de size
est transmis à PostgreSQL, PostgreSQL ne l'exigera pas.
Lors de l'utilisation d' ArrayField
il convient de garder à l'esprit ce mot d'avertissement de la documentation des baies Postgresql .
Conseil: les tableaux ne sont pas des ensembles; La recherche d'éléments de tableau spécifiques peut être un signe de mauvaise conception de la base de données. Envisagez d'utiliser une table séparée avec une ligne pour chaque élément qui serait un élément de tableau. Cela sera plus facile à rechercher et sera probablement mieux adapté à un grand nombre d'éléments.
Un ArrayField de base
Pour créer un ArrayField PostgreSQL, nous devons donner à ArrayField le type de données que nous voulons stocker en tant que champ en tant que premier argument. Comme nous allons stocker les cotes de livres, nous utiliserons FloatField
.
from django.db import models, FloatField
from django.contrib.postgres.fields import ArrayField
class Book(models.Model):
ratings = ArrayField(FloatField())
Spécification de la taille maximale d'un 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
Lorsque vous utilisez le paramètre size, il est transmis à postgresql, qui l'accepte et l'ignore ensuite! Il est donc tout à fait possible d'ajouter 7 entiers au champ scoops
ci-dessus en utilisant la console postgresql.
Demander l'appartenance à ArrayField avec contains
Cette requête renvoie tous les cônes avec un scoop au chocolat et un scoop à la vanille.
VANILLA, CHOCOLATE, MINT, STRAWBERRY = 1, 2, 3, 4 # constants for flavors
choco_vanilla_cones = IceCream.objects.filter(scoops__contains=[CHOCOLATE, VANILLA])
N'oubliez pas d'importer le modèle IceCream
partir de votre fichier models.py
.
Gardez également à l'esprit que django ne créera pas d'index pour ArrayField
. Si vous envisagez de les rechercher, vous aurez besoin d'un index qui devra être créé manuellement avec un appel à RunSQL dans votre fichier de migration.
Nid ArrayFields
Vous pouvez imbriquer ArrayField
s en passant un autre ArrayField
comme 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,
)
Interrogation pour tous les modèles qui contiennent des éléments dans une liste avec contain_by
Cette requête renvoie tous les cônes avec un scoop à la menthe ou un scoop à la vanille.
minty_vanilla_cones = IceCream.objects.filter(scoops__contained_by=[MINT, VANILLA])