June 29, 2020

How to Integrate Existing DBs with Django

How to Integrate Existing DBs with Django

Keaton Pennels

Django allows you to integrate an existing/legacy database with your current project using the inspect_db manage utility. This article will present a contrived example of integrating an existing PostgreSQL database and will follow it with a couple of “gotchas” to look out for when using inspect_db.

Setup

The database dm_blog consists of blog posts (how meta) which are associated with one of the categories specified in the category table

Step 1 is to set up a basic Django project. I’ve named mine blog_site and I’ve also created an app alongside it named blog_app as below:

├── blog_app
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── blog_site
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

Step 2 is to update the settings.py by including blog_app in the list of INSTALLED_APPS as well as updating the DATABASES dictionary with the particulars of our database.

Mine is as follows:

Inspecting

Django allows us to model our dm_blog database and place the resulting models.py in the blog_app directory by executing the following command:

python manage.py inspectdb > blog_app/models.py

Note: This command only models the tables included in your database. If you also want to include views, use this:

python manage.py inspectdb --include-views > blog_app/models.py
  • The view longest_blog displays the title and length of the longest body in the post table
  • If your database contains partitioned tables, you can include these tables in the modelling process by using the --include-partitions option (only available for PostgresDBs)

Afterwards, your models.py file should look something like this:

You can specify exactly which tables to model, by specifying the table names as arguments to the inspect_db command.

For example:

python manage.py inspectdb category
  • Then finally run the makemigrations and migrate manage.py utilities in order to finish off the modelling process (make sure to first read over the the "gotchas" below before running these commands).

Gotchas

The inspect_db utility is by no means an exhaustive means of modeling your existing database and therefore some refactoring will be required after it has been run

Here are some things to watch out for after using the inspect_db utility:

  1. In our example, the post table references the category table through its category_id field. This means that we need to rearrange the classes in models.py such that the Category model is defined before the Post model. This will ensure that the Category model is already created before the Post model references it.
  2. By default, inspect_db creates unmanaged models which means Django will not be able to manage the lifecycle of the tables it models (insert, update, delete). Remove the managed=False statements from the Meta classes of your models (or set it to True) in order to allow Django to manage your tables
  3. Django places a "This field type is a guess" comment next to any fields whose type it is unsure of. Make sure to amend the type if Django incorrectly inferred it. If there is no compatible Django field type, Django allows you to omit the field from the model definition.
  4. Django does not infer default values. These will have to be added manually

The inspect_db utility is a handy tool when dealing with pre-existing databases. Whether you want to integrate your legacy database with Django’s web framework or model your database views such that it can be exposed to a presentation layer via an API, the inspect_db utility will make the modelling process seamless.

Blog footer image