Search code examples
djangodjango-migrations

Django migration: got relation does not exist or relation already exists errors


I tried to port a Django app from one server to another and change database engine from sqllite3 to postgres. After I pulled the app from github to the new server and reconfigured database settings for postgres, I got a relation not existing error when I tried to migrate as shown below.

$ python manage.py migrate
Traceback (most recent call last):
  File "/data/apps/anaconda3/envs/parts_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedTable: relation "parts" does not exist
LINE 1: SELECT "parts"."type" FROM "parts"
...

But after I created the table in the database and tried again, I got a relation already exists error as shown below.

$ python manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, partsdb, sessions
Running migrations:
  Applying partsdb.0001_initial...Traceback (most recent call last):
  File "/data/apps/anaconda3/envs/parts_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 82, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.DuplicateTable: relation "parts" already exists
...

So I'd get the "relation does not exist" error if I dropped the table and I'd get the "relation already exists" error if I created the table.

I omitted the tracing outputs which are from Django libraries and very lengthy, but I can supply them if they may help. Thanks.

Update:

The initial migrate file (0001_initial.py) has the following lines:

from django.db import migrations, models

class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
    migrations.CreateModel(
        name='parts',
        fields=[
            ('ID', models.CharField(max_length=6, primary_key=True, serialize=False)),
            ('type', models.CharField(max_length=8)),
            ...
        ],
    ),
]
      

In the migration folder there're 3 more files (0002_alter_parts_.py, 0003_alter_parts_.py, 0004_alter_parts_*.py) and each just modified the definition of a column of the parts table (all just increased the length of the column). The parts table is the only table of the application in the database. So actually only thing I need is to create all the Django tables, such as auth_group, auth_user, etc. I can modify the model of the table and create the table from the model and load data from a dump. So what's the best way for this?


Solution

  • I found the cause of the problems and was able to resolve the problems though I still don't know why the case. So in case some one might encounter the same kind problems, the cause is that there is a class defined in a file that accesses the database table to retrieve some data, as shown in the code snip below.

    class PartsForm(forms.ModelForm):
        for type in parts.objects.values_list('type'):     
        ...
    

    I wonder why codes in this file would get executed for migration. The table parts is the only table in the database. But anyway after I moved this file out of the app, the command "python manage.py migrate" ran and finished without errors (it generated all the tables in the database including the parts table).