The django.db.utils.OperationalError: (1050, "Table '...' already exists") error means Django’s migration system tried to create a database table that’s already there, usually because the database state and Django’s migration history are out of sync.

Here’s what’s likely going on and how to fix it, starting with the most common culprits:

1. Manual Database Changes

You or someone else manually created the table in the database outside of Django’s migration process. Django’s migrations are now trying to create it again, and the database is saying "nope."

  • Diagnosis:

    • Connect to your database using a command-line client (e.g., psql, mysql, sqlite3).
    • Run a command to list tables:
    • Check if the table mentioned in the error exists. If it does, check its schema using commands like \d <table_name> (PostgreSQL) or DESCRIBE <table_name>; (MySQL).
  • Fix:

    • Option A (Recommended if the table is identical to what the migration would create): Tell Django to ignore the existing table.
      1. Find the migration file that’s trying to create the table (e.g., 0001_initial.py in your app’s migrations folder).
      2. Edit that migration file. Add migrations.RunSQL("CREATE TABLE IF NOT EXISTS appname_modelname (id serial PRIMARY KEY, ...);", reverse_sql="DROP TABLE IF EXISTS appname_modelname;") before the migrations.CreateModel operation. Replace appname_modelname and the schema with the actual table name and its structure.
      3. Then, run python manage.py migrate --fake <app_name> <migration_name> to mark this migration as applied without actually running it.
    • Option B (If the manually created table is different or you want Django to manage it): Drop the manually created table from the database.
      • PostgreSQL: DROP TABLE <table_name>;
      • MySQL: DROP TABLE <table_name>;
      • SQLite: DROP TABLE <table_name>;
      • Then, run python manage.py migrate.
  • Why it works: Option A tells Django, "This table is already here and it’s fine, consider this creation step done." Option B removes the conflicting object so Django can create it correctly.

2. Duplicate or Out-of-Order Migrations

You might have accidentally copied migration files, leading to duplicate migration names, or migrations might have been applied in an order that doesn’t match their dependencies.

  • Diagnosis:

    • Inspect your app’s migrations directory. Look for files with identical names (e.g., multiple 0001_initial.py).
    • Check the django_migrations table in your database. This table records which migrations have been applied. Look for duplicate entries for the same app and migration name, or an ordering that seems illogical.
  • Fix:

    • Remove duplicate migration files from your app’s migrations directory.
    • If you find duplicate entries in the django_migrations table, delete the duplicate rows for the specific migration that’s causing the conflict. Be careful not to delete legitimate entries.
    • Run python manage.py migrate again. If you had to manually edit the django_migrations table, you might need to use python manage.py migrate --fake <app_name> <migration_name> for the problematic migration.
  • Why it works: This cleans up the migration history and the database’s record of applied migrations, allowing Django to correctly determine which steps need to be executed.

3. Migrations Applied in a Different Environment

You might have run migrations on a different database instance (e.g., development vs. staging) and then copied the code without the corresponding database state, or vice-versa.

  • Diagnosis:

    • Compare the django_migrations table in your current database with the django_migrations table from a known good state of your application (e.g., a previous deployment or your local development environment).
    • Identify which migrations are marked as applied in one but not the other, or where the order differs.
  • Fix:

    • If the current database is missing migrations that should be applied: Run python manage.py migrate.
    • If the current database has migrations applied that are not in your code: You might need to revert those migrations (if possible and safe) or use python manage.py migrate --fake <app_name> <migration_name> for each missing migration file in your code that corresponds to an applied migration in the database.
  • Why it works: This resynchronizes the database’s migration history with the set of migrations present in your project’s codebase.

4. Accidental makemigrations After Manual Table Creation

You created a table manually, then ran python manage.py makemigrations, which created a new migration file to create that same table, even though it already exists.

  • Diagnosis:

    • Check your app’s migrations directory for a recent migration file that attempts to CreateModel for the table in question.
    • Compare the schema of the existing table in the database with the fields definition in the generated migration file.
  • Fix:

    • Delete the problematic migration file from the migrations directory.
    • Run python manage.py migrate --fake <app_name> <migration_name> for the migration that preceded the one you deleted, to ensure Django knows the state up to that point. Then run python manage.py migrate to apply any subsequent, valid migrations.
  • Why it works: This removes the redundant migration that was trying to recreate an existing object and correctly marks the previous state as applied.

5. Database Schema Drift on Cloned Projects

When cloning a project and setting up a new database, if the initial schema wasn’t properly migrated or if some manual changes were made and not reflected in the migration history.

  • Diagnosis:

    • Check the django_migrations table. Is it empty or incomplete?
    • Check the database for the existence of the table.
  • Fix:

    • Ensure your DATABASES setting is correct for the new environment.
    • Run python manage.py migrate to apply all pending migrations. If the table already exists due to a previous partial setup, you might need to use the --fake option as described in point 1. For example, if 0001_initial is the migration creating the table and it exists, run python manage.py migrate --fake <app_name> 0001_initial.
  • Why it works: This ensures the database schema is built according to the project’s defined migration history.

The Next Error You’ll Hit

If you fix the "Table Already Exists" error, the very next error you’ll likely encounter is a django.db.utils.OperationalError: (1060, "Duplicate column name '...'") if your migration also tried to add a column that already exists, or a django.db.utils.ProgrammingError: relation "..." does not exist if you accidentally dropped a table that a later migration depends on.

Want structured learning?

Take the full Django course →