pheeper
pheeper

Reputation: 1527

Django can't makemigrations after changing app name and db tables

I'm working with Django 1.11.5 and using PyCharm as my IDE. I've been trying to refactor my app name from "clinicaltrials" to "cancer_trials". PyCharm updated all of my project files accordingly. I then followed the steps in this SO answer to update the appropriate database tables. However, I'm getting the following error when I try run makemigration. I can't seem to figure out what this means and/or what part I'm missing here.

    > python manage.py makemigrations
Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "C:\Python_3.6.1\lib\site-packages\django\core\management\commands\makemigrations.py", line 150, in handle
    loader.project_state(),
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\loader.py", line 323, in project_state
    return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=list(self.unmigrated_apps))
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\graph.py", line 409, in make_state
    project_state = self.nodes[node].mutate_state(project_state, preserve=False)
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\migration.py", line 92, in mutate_state
    operation.state_forwards(self.app_label, new_state)
  File "C:\Python_3.6.1\lib\site-packages\django\db\migrations\operations\fields.py", line 142, in state_forwards
    for name, instance in state.models[app_label, self.model_name_lower].fields:
KeyError: ('cancer_trials', 'cancer_trials')

Here's the function that's throwing the error

def state_forwards(self, app_label, state):
    new_fields = []
    old_field = None
    for name, instance in state.models[app_label, self.model_name_lower].fields:
        if name != self.name:
            new_fields.append((name, instance))
        else:
            old_field = instance
    state.models[app_label, self.model_name_lower].fields = new_fields
    # Delay rendering of relationships if it's not a relational field
    delay = not old_field.is_relation
    state.reload_model(app_label, self.model_name_lower, delay=delay)

Upvotes: 2

Views: 4548

Answers (5)

Ank_247shbm
Ank_247shbm

Reputation: 540

simple approach:

Manually delete all migrations in the apps by going into each apps' 'Migrations' named directory. Note: deleting init.py in 'Migrations' named directory will not cause any harm.

Above 'appname' is apps taken one-by-one and migrated using above steps. For new apps added will only show migrated table for the next two 'migrate' and 'sqlmigrate' command work.

After this:

$: python manage.py makemigrations appname

$: python manage.py migrate appname

$: python manage.py sqlmigrate appname 0001

Upvotes: 1

raratiru
raratiru

Reputation: 9636

A nice answer on how to properly move data between apps, can be found here.

What worked for me is the following:

  1. Export the data to json

    ./manage.py dumpdata --exclude auth.permission --exclude contenttypes --exclude admin.LogEntry --exclude sessions --indent 2 > <path_out_of_the_project>/db.json
    
  2. Open the db.json file using a capable editor and rename all the instances of the old app name to the new app name.

  3. Rename your app and all the necessary references into your code.

  4. Delete the database and recreate a new empty one applying all the migrations.

  5. Load the data from the db.json file which include the new app name.

    ./manage.py loaddata <path_out_of_the_project>/db.json
    

Upvotes: 0

Borut
Borut

Reputation: 3364

In my experience the easiest solution is to create new app and copy the code:

  1. Create new app with the desired name and add it to settings
  2. Copy/paste code from old app to new app, change references from old app to new app, run makemigrations and migrate
  3. Open database and copy data from old tables to new tables
  4. Check that everything works in new app
  5. Search stackoverflow.com or google how to remove app from project or just leave in there. Unfortunately, I'm not 100 % positive about these steps, somebody please correct me if I'm wrong, but to my recollection:

Upvotes: 3

Adi Ep
Adi Ep

Reputation: 805

OK if you want to keep the existing database maybe this guide may help you: https://simpleisbetterthancomplex.com/tutorial/2016/07/26/how-to-reset-migrations.html (scenario 2)

Upvotes: 0

Adi Ep
Adi Ep

Reputation: 805

  1. Remove the all migrations files within your project Go through each of your projects apps migration folder and remove everything inside, except the init.py file.

  2. Drop the current database, or delete the db.sqlite3 if it is your case.

  3. Create the initial migrations and generate the database schema
  4. try run again migrationsa and migrate commans

Upvotes: 2

Related Questions