Django JSONField inside ArrayField

I have a problem inserting into a field using an ArrayField with an internal JSONField.

models.py

locations = ArrayField(JSONField(null = True,blank = True), blank=True, null = True) 

Embed

 location_arr = [{"locations" : "loc1","amount":Decimal(100.00)},{"locations" : "loc2","amount":Decimal(200.25)}] instance.locations = location_arr instance.save() 

When i do this i got

The "location" of the column is of type jsonb [], but the expression is of type text []

LINE 1: ... d "= 2517," locations "= ARRAY ['{" loc ...

Hint: You will need to rewrite or apply the expression.

So, I tried to reset it using:

 import json location_arr = [{"locations" : "loc1","amount":Decimal(100.00)},{"locations" : "loc2","amount":Decimal(200.25)}] instance.locations = json.dumps(location_arr) instance.save() 

then i got it

LINE 1: ... d "= 2517," locations "= '[{" loc ": ...

DETAILED DESCRIPTION: "[" must enter explicitly specified array sizes.

I use:

  • Django 1.9
  • Python 2.7
  • Postgres 9.4.10
  • psycopg2 2.6.2
+12
source share
4 answers

Arrays

First of all, let's take a close look at this important text from a Postgresql Arrays document.

Tip: arrays are not sets; a search for specific elements of an array may be a sign of incorrect database design. Try using a separate table with a row for each element that will be an element of the array. This will be easier to find, and probably scales better for a large number of elements.

Most of the time you should not use arrays.

Jsonb

JSONB is available in Django as a JSONField type. This field is more scalable and flexible than array fields and can be searched more efficiently. However, if you keep looking inside JSONB fields, the above statement about arrays is equally true for JSONB.

Now what do you have in your system? An array that contains a JSONB field. This is a disaster waiting to happen. Please normalize your data.

to recap

so when to use ArrayField?

In rare cases, when you do not need to search in this column, and you do not need to use this column to combine.

+10
source

I came across the same scenario. That's how I solved it

models.py

 from django.contrib.postgres.fields.jsonb import JSONField as JSONBField location = JSONBField(default=list,null=True,blank=True) 

Insert

 model_object.location = [{"locations" : "loc1","amount":Decimal(100.00)},{"locations" : "loc2","amount":Decimal(200.25)}] 

Update

 model_object.location.append({"locations" : "loc1","amount":Decimal(100.00)}) model_object.save() 

This worked for me in Django - 2.0.2 Postgres - 9.5 psycopg2 - 2.7.4 python - 3.4.3

+1
source

You can work around this problem by using JSONField as the column field type with list as the root element.

 from django.contrib.postgres.fields import JSONField class MyDBArray(models.Model): array_data = models.JSONField(default=list) my_db_array = MyDBArray(array_data=[1, 2, 3]) my_db_array.save() 

You need to check in the save method that the array_data field actually looks like a list.

0
source

This has been fixed in the latest unreleased version of Django 2.2a1

pip install Django==2.2a1

PS I believe that it will work with versions >= 2.2a1

0
source

Source: https://habr.com/ru/post/1013139/


All Articles