'How can I change charset and collation with Django's migrations?

I have a character field that's utf8 I want it to be utf8mb4, how do I accomplish that with Django's migrations?



Solution 1:[1]

Django doesn't have support for different character sets. You tell it CharField, it uses Unicode internally, it uses UTF-8 when talking to the RDBMS, and it's the RDMBS's job to convert the strings into the encoding it uses for storage.

From https://docs.djangoproject.com/en/1.10/ref/databases/#encoding:

Django assumes that all databases use UTF-8 encoding.

Note that the thing MySQL calls utf8mb4 is what everyone else (including Django) calls UTF-8, and that what MySQL calls utf8 is a subset of UTF-8 that doesn't exist elsewhere.

So Django doesn't support any messing around with the encodings of char fields of the database. It expects you to create the database with an encoding supporting all Unicode characters, and for the RDBMS to use UTF-8 when communicating with the database client (i.e. with Django).

Solution 2:[2]

You can add a custom SQL migration.

  1. Create an empty migration with ./manage.py makemigrations <app> --empty --name <a_good_name>
  2. Add a migrations.RunSQL operation to the operations list. You can just add the sql (and reverse_sql if you want it to be reversible). No need to add a state operation.
  3. Run ./manage.py migrate!

You're SQL would look something like:

ALTER TABLE `my_table`
CHANGE `my_column` `my_column` longtext 
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL;'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Antonis Christofides
Solution 2 Tino