django.db.utils.ProgrammingError: relation already exists

前端 未结 12 692
一向
一向 2020-12-23 14:11

I\'m trying to set up the tables for a new django project (that is, the tables do NOT already exist in the database); the django version is 1.7 and the db back end is Postgr

相关标签:
12条回答
  • 2020-12-23 14:51

    This works pretty fine

    ./manage.py migrate --fake default
    

    Source: -https://github.com/nijel/weblate/issues/587

    0 讨论(0)
  • 2020-12-23 14:51

    Been facing a similar issue, eventually deleted all .py files in migration folder (django 1.7 creates one automatically), worked perfectly after that.

    0 讨论(0)
  • 2020-12-23 14:52

    I've faced similar issue when added couple new fields to existing model. I'm using Django 1.9, which introduced --run-syncdb option. Running manage.py migrate --run-syncdb fixed my tables.

    0 讨论(0)
  • 2020-12-23 14:52

    Do not try to use --fake, because with this you risk corrupting your database.

    Instead, you can backup your current database, recreate it, and then apply backup.

    1. Create backup: pg_dump -F c -v -h localhost <database_name> -f tmp/<pick_a_file_name>.psql

    2. Recreate it: rails db:drop db:create

    3. Restore backup: pg_restore --exit-on-error --verbose --dbname=<database_name> tmp/<pick_a_file_name>.psql

    0 讨论(0)
  • 2020-12-23 14:53

    I've been dealing with this for several years. There could be different scenarios:

    Scenario 1: as in the original post, you had no tables to start with. In this case, I'd

    1. comment out the relationship in models.py
    2. run python manage.py
    3. migrate assuming that it now succeeds
    4. uncomment what you
    5. commented out in step 1 run python manage.py migrate --fake

    Scenario 2: multiple apps: One possibility is that you might have different apps and the data model of one app is using some tables from the other app. In this case, if the data model is designed properly, you should be able to create the tables for one app only (by specifying only that one in setting.py), then add the other app and migrate. If it is not design with care, and there are recursive dependencies, I suggest changing the design rather than making a temporary fix.

    Scenario 3: you had some tables and something went wrong with your migration, then I'd

    1. revert models.py to what it was and only introduce the new relationship that appears to already exist in models.py.
    2. delete migration folder
    3. run python manage.py makemigrations
    4. introduce new changes to models.py if any and continue with makemigrations and migrate commands as usual.
    0 讨论(0)
  • 2020-12-23 14:54

    Django provides a --fake-initial option which I found effective for my use. From the Django Migration Documentation:

    --fake-initial

    Allows Django to skip an app’s initial migration if all database tables with the names of all models created by all CreateModel operations in that migration already exist. This option is intended for use when first running migrations against a database that preexisted the use of migrations. This option does not, however, check for matching database schema beyond matching table names and so is only safe to use if you are confident that your existing schema matches what is recorded in your initial migration.

    For my use, I had just pulled a project from version control and was preparing to add some new model fields. I added the fields, ran ./manage.py makemigrations and then attempted to run ./manage.py migrate which threw the error since, as one would expect, many of the fields already existed in the existing database.

    What I should have done was to run makemigrations immediately after pulling the project from versions control to create a snapshot of existing models' state. Then, running the ./manage.py migrate --fake-initial would be the next step.

    After that you can add away and makemigrations > migrate as normal.

    NOTE: I do not know if a --fake-initial would skip existing fields and add new ones. I opted to comment out the new fields I'd created up to that point, run the --fake-initial as if it were the first thing I did after pulling from version control, then added in updated fields in the next migration.

    Other related documentation: https://docs.djangoproject.com/en/dev/topics/migrations/#initial-migrations

    0 讨论(0)
提交回复
热议问题