How to remove an app from a django projects (and all its tables)
Asked Answered
J

3

13

I want to remove an app from a django project.

I want to remove

  • the tables of the app
  • the content-types
  • foreign-key usages of these content-types

Running manage.py migrate app_to_remove zero does not work:

django.db.migrations.migration.IrreversibleError: 
Operation <RunPython <function forwards_func at 0x7ff76075d668>> in
            fooapp.0007_add_bar is not reversible

I guess there are several migrations which are not reversible ...

Jaclynjaco answered 2/3, 2016 at 10:57 Comment(2)
Possible duplicate of Remove app (and associated database tables) in Django 1.7Rafat
@Rafat thank you for this hint. Running manage.py migrate app_to_remove zero does not work. I updated the question.Jaclynjaco
J
23

First: Remove references in the code

  • remove app_to_remove from settings.INSTALLED_APPS
  • remove other references in urls.py or other places

Second: Clean the database

Create an empty migration for your django-project:

manage.py makemigrations your_django_project --empty

Edit the file. Here is a template:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('your_django_project', '0001_initial'),
    ]

    operations = [
        migrations.RunSQL('''
        drop table if exists app_to_remove_table1;
        drop table if exists app_to_remove_table2;
        ....
        delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '{app_label}');
        delete from django_admin_log where content_type_id in (select id from django_content_type where app_label = '{app_label}');
        delete from django_content_type where app_label = '{app_label}';
        delete from django_migrations where app='{app_label}';
        '''.format(app_label='app_to_remove'))
    ]

Run the migration, run tests.

About "drop if exists": You have two cases:

  1. The production system: You want to drop the tables.
  2. New development systems: These systems never had this app, and they don't have this table :-)
Jaclynjaco answered 2/3, 2016 at 10:57 Comment(11)
I'm using Django 1.10 with PostgreSQL. Instead of your_django_project I would say your_app. Then, the order of the steps is the oposite: first you clean the DB (you need that the app is installed to be able to create migrations). Next you uninstall the app. Also, in my case the correct syntax is: drop table if exists app_to_remove_table1; ... postgresql.org/docs/8.2/static/sql-droptable.html Finally, I had to remove the line: delete from reversion_version where ....Honeydew
In django 1.10, this method can't be used to remove a second app. Using a migration to remove data adds a row to the migrations table.Honeydew
With django terminology, the project is the container for N apps. For me adding the migration to your_django_project looks right. I want the uninstall to happen in one step. 1) The code in the production virtualenv gets updated. This means "app_to_remove" is not in INSTALLED_APPS any more. This means I need to store the migration somewhere else. 2) the migrations get run. I guess I understand what you mean. The app could to do "hara-kiri" (kill itself). But maybe it is a re-usable app, and I just want it to vanish in one project.Jaclynjaco
Ok, I kind-of understand your point. Even though it makes sense, I still can't execute the commands you mention. Did you try to do what you are proposing? in what Django version is it working?Honeydew
@Honeydew yes, I used this recipe myself twice. Maybe it contains a copy+paste error. What error message do you get?Jaclynjaco
App 'your_django_project' could not be found. Is it in INSTALLED_APPS? (of course, using the real django_project name). The makemigrations command expects an app name. But such apps were uninstalled in the first step.Honeydew
@Honeydew if you used jango-admin startproject mysite then replace "your_django_project" with "mysite".Jaclynjaco
This seems like a very manual and error prone way to do this?Synergism
This is a good solution. It is declarative and most importantly, idempotent. Do not fear a little SQL in your life.Stated
To make the drop table statements more robust, add CASCADE to the end of each drop table statement. It will not delete the dependent table (those with foreign keys) but only remove the foreign key constraint. Also, SQL in lowercase?! :DIngrowing
I also have to add delete from auth_group_permissions where permission_id in (select id from auth_permission where content_type_id in (select id from django_content_type where app_label = '{app_label}')); before deletion from auth_permissionFlexion
B
2

This is what the official documentation suggests for the latest version as of now, which is 4.2:

  1. Remove all references to the app (imports, foreign keys etc.).
  2. Remove all models from the corresponding models.py file.
  3. Create relevant migrations by running makemigrations. This step generates a migration that deletes tables for the removed models, and any other required migration for updating relationships connected to those models.
  4. Squash out references to the app in other apps’ migrations.
  5. Apply migrations locally, runs tests, and verify the correctness of your project.
  6. Deploy/release your updated Django project.
  7. Remove the app from INSTALLED_APPS.
  8. Finally, remove the app’s directory.
Bryant answered 20/9, 2023 at 9:51 Comment(0)
S
1

Note: this guide is successful with Django 3.1.1 and Python 3.8.2

Can you try this solution to clean your database and migrations first

Step 1: Delete your table from the file your_app/models.py but leave the file itself

Step 2: Check your register in the file admin.py if you have

Step 3: create migration:

manage.py makemigrations your_app

Step 4: migrate into database:

manage.py migrate

you can see the result in my example enter image description here

Step 5: delete all the files in the folder your_app/migrations

Step 6: Remove migrations in the table django_migrations

python manage.py migrate --fake your_app zero

Check migrations:

python manage.py showmigrations

Step 7: Then you can remove the app completely,check reference,INSTALLED_APPS

Stir answered 7/10, 2020 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.