Skip to content

Instantly share code, notes, and snippets.

@brutus
Created June 30, 2017 14:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brutus/b000ecd35fdb0d61e7259b7424998cc4 to your computer and use it in GitHub Desktop.
Save brutus/b000ecd35fdb0d61e7259b7424998cc4 to your computer and use it in GitHub Desktop.
Converts the collation and character set of a database using a Django migration.
"""
Converts the *collation* and *character set* of a database using a Django
migration. Data in the tables is converted if needed.
"""
from django.db import migrations
def get_conversion_function(collation, character_set='utf8'):
"""
Returns a function that sets the given *collation* and *character_set*.
Args:
collate: e.g. `utf8_general_cs`, `utf8_general_ci` or `utf8_bin`…
character_set: e.g. `utf8`, `latin1`…
"""
def alter_collation_from_migration(apps, schema_editor):
"""
Sets *collation* and *character_set* for a database and its tables.
Also converts data in the tables if necessary.
"""
with schema_editor.connection.cursor() as cursor:
# set for database
print('Altering database…')
cursor.execute(
f'ALTER DATABASE CHARACTER SET {character_set} COLLATE {collation};'
)
# set for tables (and convert data)
cursor.execute(
'SHOW TABLES;'
)
for table, in cursor.fetchall():
print(f'Altering table `{table}`…')
cursor.execute(
f'ALTER TABLE {table} CONVERT TO CHARACTER '
f'SET {character_set} COLLATE {collation}'
)
return alter_collation_from_migration
class Migration(migrations.Migration):
"""
Runs :func:`alter_collation_from_migration` with the given args.
You need to set the :attr:`dependencies`. To figure out what to fill in run
``django-admin makemigrations myapp --empty``.
"""
dependencies = [
# Needs to be filled!
]
operations = [
migrations.RunPython(get_conversion_function('utf8_general_ci')),
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment