50

How to get all table names in a Django app?

I use the following code but it doesn't get the tables created by ManyToManyField

from django.db.models import get_app, get_models
app = get_app(app_name)
for model in get_models(app):
    print model._meta.db_table
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jack
  • 17,261
  • 37
  • 100
  • 125

4 Answers4

85

This will give you all of the table names, like the OP asks for:

from django.apps import apps

tables = [m._meta.db_table for c in apps.get_app_configs() for m in c.get_models()]

This will give you all model names:

from django.db import connection
tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)

This will give you all of the model names on a per app basis:

from django.apps import apps 
from django.contrib import admin 
from django.contrib.admin.sites import AlreadyRegistered 

app_models = apps.get_app_config('my_app').get_models()

Additional reading

And yet another recommends reading this answer:

Django get list of models in application

metersk
  • 11,803
  • 21
  • 63
  • 100
cethegeek
  • 6,286
  • 35
  • 42
  • Edited to include the mechanism to get only the installed apps models. I really recommend looking at the syncdb command code. – cethegeek Dec 04 '09 at 14:42
  • This answer lists all the tables that my django has ever used, including those created by apps that were once in INSTALLED_APPS but no longer are. Is there a way to find out the ones that are currently relevant? – GreenAsJade Dec 07 '14 at 21:32
  • For future references: https://stackoverflow.com/a/31184258/1937033 From Django 1.7 on, you can use this code, for example in your admin.py to register all models: `from django.apps import apps from django.contrib import admin from django.contrib.admin.sites import AlreadyRegistered app_models = apps.get_app_config('my_app').get_models() for model in app_models: try: admin.site.register(model) except AlreadyRegistered: pass` – ThePhi Nov 08 '17 at 19:14
  • @ThePhi I added that to the answer. Haven't tested though. – cethegeek Nov 09 '17 at 19:58
  • 1
    it works by my testing, 1.11. However, note that `app_models` is an iterable that you can only iterate through once, so maybe best to do `app_models = list(app_models)` for durability. – AlanSE Mar 16 '18 at 19:16
  • 3
    You can list all table names via: ```[ m._meta.db_table for c in apps.get_app_configs() for m in c.get_models() ]``` – cdosborn Mar 30 '18 at 23:01
  • Thanks @cdosborn, nice and effective. Plus, it gives the list of tables, not the models. For getting the list of models I liked better the `dict(apps.all_models[''])` found here https://stackoverflow.com/questions/8702772/django-get-list-of-models-in-application/31184258#answer-39661207 (both tested in django 2.2) – Giampaolo Ferradini May 02 '20 at 01:42
  • @cethegeek, Clean & tidy! where to find the document/manual for `connection.introspection`, please? – NegaOverflow May 22 '20 at 20:58
  • 1
    @NegaOverflow, to my knowledge such documentation doesn't exist. But you can read the code (for mysql) here: https://github.com/django/django/blob/master/django/db/backends/mysql/introspection.py and for other databases start here: https://github.com/django/django/tree/master/django/db/backends and navigate to your known backend and open introspection.py. Good luck. – cethegeek May 23 '20 at 21:12
11

The simplest answer, that still allows you to pick which app you want, is to modify your code with one extra argument "include_auto_created".

from django.db.models import get_app, get_models
app = get_app(app_name)
for model in get_models(app, include_auto_created=True):
    print model._meta.db_table

Obviously I got this by following celope's advice to read the syncdb source, so thanks for that - just documenting an exact answer that includes the app name as it was what I wanted and possibly others too in future.

George Lund
  • 1,269
  • 12
  • 16
2

This works for

>>> python -m django version
2.0.7

OK, here's how you do that:

>>> from django.apps import apps 
>>> polls_tables = apps.get_app_config("polls")
>>> polls_tables.models
OrderedDict([('question', <class 'polls.models.Question'>), ('choice', <class 'polls.models.Choice'>), ('reporter', <class 'polls.models.Reporter'>), ('article', <class 'polls.models.Article'>), ('publication', <class 'polls.models.Publication'>), ('publicationarticle_publications', <class 'polls.models.PublicationArticle_publications'>), ('publicationarticle', <class 'polls.models.PublicationArticle'>), ('person', <class 'polls.models.Person'>), ('group', <class 'polls.models.Group'>), ('membership', <class 'polls.models.Membership'>), ('place', <class 'polls.models.Place'>), ('restaurant', <class 'polls.models.Restaurant'>), ('waiter', <class 'polls.models.Waiter'>), ('student', <class 'polls.models.Student'>), ('assembler', <class 'polls.models.Assembler'>), ('bike', <class 'polls.models.Bike'>), ('blog', <class 'polls.models.Blog'>), ('author', <class 'polls.models.Author'>), ('entry_authors', <class 'polls.models.Entry_authors'>), ('entry', <class 'polls.models.Entry'>), ('themeblog', <class 'polls.models.ThemeBlog'>), ('bookauthor', <class 'polls.models.BookAuthor'>), ('publisher', <class 'polls.models.Publisher'>), ('book_authors', <class 'polls.models.Book_authors'>), ('book', <class 'polls.models.Book'>), ('store_books', <class 'polls.models.Store_books'>), ('store', <class 'polls.models.Store'>), ('dummy', <class 'polls.models.Dummy'>)])
>>> polls_tables.models.keys()
odict_keys(['question', 'choice', 'reporter', 'article', 'publication', 'publicationarticle_publications', 'publicationarticle', 'person', 'group', 'membership', 'place', 'restaurant', 'waiter', 'student', 'assembler', 'bike', 'blog', 'author', 'entry_authors', 'entry', 'themeblog', 'bookauthor', 'publisher', 'book_authors', 'book', 'store_books', 'store', 'dummy'])

you can also get field names of particular model

>>> questionTable = polls_tables.get_model("question")
>>> questionTable._meta.get_fields()
(<ManyToOneRel: polls.choice>, <django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: question_text>, <django.db.models.fields.DateTimeField: pub_date>)

Further if you want you can get count of it by

>>> len(questionTable._meta.get_fields())
4

To get all the values in database, you can do it as:

>>> list = [entry for entry in Entry.objects.values()]
>>> for dict in list:
...     print()
...     for key in dict:
...             print(key," : ", dict[key]) 
... 

id  :  1
blog_id  :  5
headline  :  i have blog entry named DJANGO
pub_date  :  2018-06-10
n_comments  :  5
n_pingbacks  :  1

id  :  2
blog_id  :  5
headline  :  i have blog entry named DJANGO
pub_date  :  2018-06-10
n_comments  :  7
Gambitier
  • 504
  • 6
  • 18
0

The simplest method should be to use the database reflection APIs in django to go directly to the database. The drawback to this is that it won't give you any tables before you've synced.

boxed
  • 3,895
  • 2
  • 24
  • 26