Last active
November 17, 2016 21:51
-
-
Save strix/228263d77229ddf8f0530a3c1c447ec9 to your computer and use it in GitHub Desktop.
Django management command to change app names
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from django.core.management.base import BaseCommand, CommandError | |
| from django.db import connection | |
| from django.apps import apps | |
| class Command(BaseCommand): | |
| help = ('Renames an app in the database. You will need to change imports and migrations manually') | |
| def add_arguments(self, parser): | |
| # Positional arguments | |
| parser.add_argument('old_app_name') | |
| parser.add_argument('new_app_name') | |
| # Optional arguments | |
| parser.add_argument('--dry-run', | |
| action='store_true', | |
| dest='dry', | |
| default=False, | |
| help='Only print out sql commands that would execute') | |
| def handle(self, *args, **options): | |
| old_app_name = options['old_app_name'] | |
| new_app_name = options['new_app_name'] | |
| self.stdout.write(old_app_name) | |
| self.stdout.write(new_app_name) | |
| sql_commands = [] | |
| app = apps.get_app_config(old_app_name) | |
| django_content_update = "UPDATE django_content_type SET app_label='{}' WHERE app_label='{}'".format(new_app_name, old_app_name) | |
| migration_app_change = "UPDATE django_migrations SET app='{}' WHERE app='{}'".format(new_app_name, old_app_name) | |
| change_model_tables = "ALTER TABLE {} RENAME TO {}" | |
| # postgres specific??? needed??? (also below) | |
| postgres_seq_update = "ALTER SEQUENCE {}_id_seq RENAME TO {}_id_seq" | |
| sql_commands.extend([ | |
| ('Updating django_content_type...', django_content_update), | |
| ('Updating migrations in db...', migration_app_change), | |
| ]) | |
| for model_name, model in app.models.items(): | |
| old_table_name = model._meta.db_table | |
| new_table_name = new_app_name + '_' + old_table_name.split('_')[1] | |
| sql_commands.append(('Changing table {} to {}'.format(old_table_name, new_table_name), change_model_tables.format(old_table_name, new_table_name))) | |
| # postgres specific??? needed??? (also above) | |
| sql_commands.append(('Change sequence of {} to {}'.format(old_table_name, new_table_name), postgres_seq_update.format(old_table_name, new_table_name))) | |
| self.stdout.write('Establishing connection to run commands...') | |
| with connection.cursor() as cursor: | |
| for message, command in sql_commands: | |
| self.stdout.write(message) | |
| if options['dry']: | |
| self.stdout.write('WOULD EXECUTE (dry run): ' + command) | |
| else: | |
| self.stdout.write('EXECUTING: ' + command) | |
| cursor.execute(command) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
NOTE: This management command must be executed BEFORE changing any folder/app names
Run
./manage.py renameapp --helpto see the full description of the commandotherwise run
./manage.py renameapp old_app_name new_app_nameto executeor
./manage.py renameapp old_app_name new_app_name --dry-runto only print the sql commands it will executeThese commands were derived from this answer on stackoverflow
Feedback or corrections are encouraged