In my models I have old field tag
and created new one tags
.
class YOUR_MODEL():
tag = models.CharField(max_length=64, null=True, default=None, db_index=True, choices=[(tag, tag) for tag in TAGS])
tags = ArrayField(models.CharField(max_length=64, choices=[(tag, tag) for tag in TAGS]), db_index=True, null=True)
Column tag
have only strings, for example ‘APPLE’ or ‘PEAR’.
I want that column tags
to be an array of one string after migrations.
Also:
TAGS = field_types.FORM_FIELD_TAGS
FORM_FIELD_TAGS = [
FORM_FIELD_APPLE_TAG,
FORM_FIELD_PEAR_TAG,
]
FORM_FIELD_APPLE_TAG = 'APPLE'
FORM_FIELD_PEAR_TAG = 'PEAR'
In my migrations after creating new field and before deleting old one I want to transfer data from column tag
into tags
. I tried using raw sql: cursor.execute("UPDATE form_builder_formfield SET tags = ARRAY[tag] WHERE tag IS NOT NULL")
but this is not working.
I recived errors:
django.db.utils.DataError: malformed array literal: "["APPLE"]"
"[" must introduce explicitly-specified array dimensions.
I also tried using django queryset but I always end with this errors above. Any ideas how to do it?
2
Answers
Okay. So I found a solution. Code was all right. The problem was elsewhere. I had a trigger on a database that was changing '{' curly braces into '[' square braces. So even if I explicitly typed '{' into code it anyway changed it to '[', so postgres couldn't create an array.
Thanks for trying to help.
You can add to your migration a RunPython operation. Make a migration, that has 2 operation: adds a new field
tags
and removes oldtag
. Between them add a operation bellow:You can make
migrate_tag_data
however you like, but I suggest code bellow. Just put it at start of migration file.Then migrate and you’re good!