How I Moved Django Models Between Apps Without Losing Data

How I Moved Django Models Between Apps Without Losing Data

🚀 Introduction

In a recent project, I encountered a common yet sensitive challenge: migrating Django models from one application to another during a major codebase restructure, without losing any data.

If you’ve ever dealt with Django migrations, you’ll know that messing with app structure can quickly lead to broken migrations or worse — data loss.

In this post, I’ll walk you through the 9-step strategy I used to safely move models between Django apps. No hacks. No raw SQL. Just careful use of Django's migration system.

🏗️ Problem

We needed to move several models from one Django app to another as part of a domain reorganization effort. But these models had already been in production, holding critical data.

That meant:

  • No changing database table names
  • No losing migration history
  • No manual intervention in the DB

✅ Solution Overview

The solution was split into two iterations:

  • First Iteration: Shift code while keeping the database untouched
  • Second Iteration: Finalize table ownership and clean up metadata

🔄 First Iteration: Safe Transfer of Code

1. Move the Models to the New App

Move the model code from the original app to the new app’s models.py.

✅ Tip: Don’t remove the models from the old app just yet, we’ll deal with that shortly.

2. Add Meta.db_table to Preserve Table Names

In the new app, update each model with its original database table name:

class MyModel(models.Model):
    ...

    class Meta:
        db_table = 'original_table_name'        

This ensures Django will not attempt to create a new table.

3. Create Migrations in Both Apps

Run:

python manage.py makemigrations old_app
python manage.py makemigrations new_app        

This will generate a set of migrations, one removing models from the old app and one adding them to the new app.


4. Use SeparateDatabaseAndState

Now, edit both migration files to use Django's SeparateDatabaseAndState so that only Django’s model state changes, not the actual DB schema.

from django.db.migrations.operations.special import SeparateDatabaseAndState

operations = [
    SeparateDatabaseAndState(
        database_operations=[],
        state_operations=[
            migrations.CreateModel(...),  # or DeleteModel for old app
        ]
    )
]        
This tells Django: “Update the Python model history, but leave the database tables untouched.”

5. Comment Out Delete Operations in Old App

In the old app’s migration, find and comment out any DeleteModel operations, just to be extra safe.


6. Apply the Migrations

Once both migration files are ready and safe, apply them:

python manage.py migrate        

Your models are now officially moved — at least in Django’s eyes — while the database remains stable and intact.


🔁 Second Iteration — Finalizing the Move

7. Remove Meta.db_table

Once Django knows the models "belong" to the new app, you can safely remove the db_table overrides.

class MyModel(models.Model):
    ...

    class Meta:
        pass  # or delete the Meta class entirely if not needed        

8. Create New Migrations

Generate a fresh migration in the new app:

python manage.py makemigrations new_app        

This migration tells Django to stop overriding the DB table name and use the default.


9. Run Final Migration

Apply the last migration:

python manage.py migrate        

That’s it. The models now fully belong to the new app, and all data is intact.


🧠 Lessons Learned

  • Never rush migrations — especially in production.
  • Use SeparateDatabaseAndState() When Django's default behavior isn't safe.
  • Avoid renaming models and moving them simultaneously; do it in separate steps.


💬 Conclusion

Moving models between Django apps isn't something you do every day, but when you do, doing it safely is critical.

By splitting the process into two controlled iterations and leveraging Django’s migration tools properly, I was able to restructure the project without data loss or migration corruption.

Syed Naqi

Associate Software Engineer @ Tkxel | Python | React | Full-Stack Developer

1mo

Helpful insight, Osama

Like
Reply
Muhammad Saad Zubair

SWE Intern @ Reka Studios | PUCIT'27 | Data Enthusiast | Python | C++ | Machine Learning | SQL | Streamlit | JavaScript (React) || AI enthusiast

1mo

Informative.

Ali Amanat Ali

Software Engineer @ Devsinc | I build scalable software solutions |

1mo

Insightful, thanks for sharing Osama.

Kabeer Ali

Software engineer (.NET Azure) || .NET || React js || Azure Integrations || Azure Devops || Microsoft Dynamic 365 CRM || Power Platform

1mo

Worth read.

To view or add a comment, sign in

Others also viewed

Explore topics