Django
ArrayField - un campo específico de PostgreSQL
Buscar..
Sintaxis
- desde django.contrib.postgres.fields importa ArrayField
- clase ArrayField (campo base, tamaño = Ninguno, ** opciones)
- FooModel.objects.filter (array_field_name__contains = [objetos, to, check])
- FooModel.objects.filter (array_field_name__contained_by = [objetos, a, verificar])
Observaciones
Tenga en cuenta que aunque el parámetro de size
se pasa a PostgreSQL, PostgreSQL no lo aplicará.
Cuando use ArrayField
s, debe tener en cuenta esta palabra de advertencia de la documentación de matrices de Postgresql .
Consejo: Las matrices no son conjuntos; la búsqueda de elementos de una matriz específica puede ser un signo de mal diseño de la base de datos. Considere usar una tabla separada con una fila para cada elemento que sería un elemento de matriz. Esto será más fácil de buscar y es probable que se escale mejor para una gran cantidad de elementos.
Un ArrayField básico
Para crear un ArrayField de PostgreSQL, deberíamos darle a ArrayField el tipo de datos que queremos que almacene como un primer campo como campo. Ya que estaremos almacenando calificaciones de libros, usaremos FloatField
.
from django.db import models, FloatField
from django.contrib.postgres.fields import ArrayField
class Book(models.Model):
ratings = ArrayField(FloatField())
Especificando el tamaño máximo de 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
Cuando usas el parámetro size, se pasa a postgresql, que lo acepta y luego lo ignora. Por lo tanto, es muy posible agregar 7 enteros al campo de scoops
arriba usando la consola postgresql.
Consultando la pertenencia a ArrayField con contiene
Esta consulta devuelve todos los conos con una cucharada de chocolate y una cucharada de vainilla.
VANILLA, CHOCOLATE, MINT, STRAWBERRY = 1, 2, 3, 4 # constants for flavors
choco_vanilla_cones = IceCream.objects.filter(scoops__contains=[CHOCOLATE, VANILLA])
No olvide importar el modelo IceCream
desde su archivo models.py
.
También tenga en cuenta que django no creará un índice para ArrayField
s. Si va a buscarlos, necesitará un índice y tendrá que crearlo manualmente con una llamada a RunSQL en su archivo de migraciones.
Matrices de nidificación
Puede anidar ArrayField
s pasando otro ArrayField
como 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,
)
Consultar a todos los modelos que contengan cualquier artículo en una lista con contenido por
Esta consulta devuelve todos los conos con una cucharada de menta o una cucharada de vainilla.
minty_vanilla_cones = IceCream.objects.filter(scoops__contained_by=[MINT, VANILLA])