Django: find ghost tables without associated models

Who you gonna call? Ghost-table-busters!

Heavy refactoring of models can leave a Django project with “ghost tables”, which were created for a model that was removed without any trace in the migration history. Thankfully, by using some Django internals, you can find such tables.

Use the database introspection methods table_names() to list all tables and django_table_names() to list tables associated with models. By casting these to sets, you can subtract the latter from the former to find tables not associated with a model:

In [1]: from django.db import connection

In [2]: table_names = set(connection.introspection.table_names())

In [3]: django_table_names = set(connection.introspection.django_table_names())

In [4]: table_names - django_table_names - {"django_migrations"}
Out[4]:
{'sweetshop_humbug',
'sweetshop_jellybean',
'sweetshop_marshmallow'}

Note the django_migrations table needs excluding. This is Django’s internal table for tracking migrations, which has no associated (permanent) model.

From here, you’ll want to make a judgement call on what to do with the tables. Perhaps some should have models created whilst others can be removed.

To generate a model for a ghost table, use the inspectdb management command:

$ ./manage.py inspectdb sweetshop_humbug
# This is an auto-generated Django model module.
# ...
from django.db import models


class SweetshopHumbug(models.Model):
  id = models.BigAutoField(primary_key=True)
  ...

If a ghost table has no useful data or references in migrations, consider dropping it directly with SQL, rather than adding a migration. Make sure you have a backup, just in case! You can drop using dbshell. For example, using PostgreSQL:

$ ./manage.py dbshell
psql (...)
Type "help" for help.

candy=# DROP TABLE sweetshop_humbug;
DROP TABLE

Fin

May your database not be haunted by the ghosts of tickets past,

—Adam


😸😸😸 Check out my new book on using GitHub effectively, Boost Your GitHub DX! 😸😸😸


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: