Django is designed to work with a Django-specific database, that the framework builds and manages through the core Django models (e.g. for authentication) and the data models that you create. It’s a fantastic system, and has been improved massively by including migrations in the Django core from version 1.7 (previously migrations were best dealt with by the fabulous South package developed here in Oxford by the friendly folk at Torchbox). However, sometimes the occasion arises where you want to use an existing database with Django, which is a little trickier, but after combining digging around a few resources, plus some testing, is actually pretty straightforward.
The individual steps listed below are to integrate a legacy MySQL database (legacydb
) with a brand new Django project. The codeblocks show either commands run, or changes to the Django project code.
- Create an app within the Django project
$ ./manage.py startapp legacydbapp
- Add config for legacy database to project settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }, 'legacydb': { 'NAME': 'legacydb_name', 'ENGINE': 'django.db.backends.mysql', 'USER': 'username', 'PASSWORD': 'password' } }
- Auto-generate the models and save to the models.py file in the new app.
$ ./manage.py inspectdb --database=legacydb > legacydb/models.py
inspectdb
is a shortcut for model generation, but the models need to be edited manually in order to fulfil a number of criteria (which are listed in the file by theinspectdb
tool):- Rearrange models’ order
- Make sure each model has one field with primary_key=True
- Make sure each ForeignKey has
on_delete
set to the desired behavior. - Remove
managed = False
lines if you wish to allow Django to create, modify, and delete the table - NB, by default, model.py files have a utf-8 declaration at the top of the file, which is not included by
inspectdb
. Add manually if needed.# -*- coding: utf-8 -*-
- Run migration for the new database (NB the app is not specified here, but can be)
$ ./manage.py makemigrations $ ./manage.py migrate
- There are two ways of using the legacy database within the project for fetching/writing data. The first way is to specify which database to use directly in
legacydb/views.py
e.g. via theusing()
QuerySet method, which tells Django to use a specific database for a that operation. e.g. in legacydb/views.pypages = Page.objects.using('legacydb').all()
- Alternatively, a better option, with more concise code is to use Database Routing, which determines when each database will be used. For more details, see https://strongarm.io/blog/multiple-databases-in-django/ and https://stackoverflow.com/questions/18547468/multiple-databases-and-multiple-models-in-django
References:
- Django Documentation - Integrating Django with a legacy database
- Django Documentation - Multiple databases
- Multiple Databases in Django
- How to Configure Multiple Databases in Django the Simple Way
- Multiple databases and multiple models in Django
- Django multi-database routing
- Adding a second legacy database to an existing django 1.2 project