Skip to content

Instantly share code, notes, and snippets.

@strix
Last active November 17, 2016 21:51
Show Gist options
  • Save strix/228263d77229ddf8f0530a3c1c447ec9 to your computer and use it in GitHub Desktop.
Save strix/228263d77229ddf8f0530a3c1c447ec9 to your computer and use it in GitHub Desktop.
Django management command to change app names
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)
@strix
Copy link
Author

strix commented Nov 17, 2016

NOTE: This management command must be executed BEFORE changing any folder/app names
Run ./manage.py renameapp --help to see the full description of the command
otherwise run ./manage.py renameapp old_app_name new_app_name to execute
or ./manage.py renameapp old_app_name new_app_name --dry-run to only print the sql commands it will execute
These commands were derived from this answer on stackoverflow
Feedback or corrections are encouraged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment