How To Migrate From SQLite To PostgreSQL In Django In 3 steps
Replicate the same database structure and data
Overview
So your Django project has already grown and you need to migrate your data from the default SQLite1 basic database to PostgreSQL2.
This tutorial assumes you have already configured a PostgreSQL database in another server, we will just focus in migrating all the data and database structure.
Steps
1. Dump Sqlite Data
We will dump all the data from the sqlite database with the command3
manage.py dumpdata
, and redirect the output to a file > dump.json
, in this way,
we will create a dump file with all installed applications data in the database.
$ ./manage.py dumpdata --indent 4 > dump.json
This command has two special parameters worth noting, that may be useful depending on how you designed your application.
--natural-foreign
- Uses the natural_key() model method to serialize any foreign key and many-to-many relationship to objects of the type that defines the method. If you’re dumping contrib.auth Permission objects or contrib.contenttypes ContentType objects, you should probably use this flag. 4
This basically means that if you get error mes
--natural-primary
- Omits the primary key in the serialized data of this object since it can be calculated during deserialization. 5
In Django terminology, we are creating a fixture, “a file that contain the serialized contents of the database”6
Data serialization is the process of converting structured data to a format that allows sharing or storage of the data in a form that allows recovery of its original structure
2. Create Tables in PostgreSQL
On the new Django instance which has PostgreSQL configured, Create the
required structure in the new database with the migration command:
./manage migrate
7
$ ./manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, games, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying auth.0012_alter_user_first_name_max_length... OK Applying games.0001_initial... OK Applying games.0002_auto_20200825_1236... OK Applying games.0003_auto_20200825_1326... OK Applying games.0004_auto_20200825_1413... OK Applying games.0005_auto_20200825_1416... OK Applying games.0006_auto_20200825_1635... OK Applying games.0007_auto_20200825_1635... OK Applying games.0008_auto_20200825_1652... OK Applying games.0009_auto_20200825_1705... OK Applying games.0010_auto_20200825_1900... OK Applying games.0011_auto_20200828_1851... OK Applying games.0012_auto_20200828_1852... OK Applying games.0013_auto_20200828_1907... OK Applying sessions.0001_initial... OK $
3. Load data
We are ready to load the dumped data into the new database with:
./manage loaddata
.8
$ ./manage.py loaddata dump.json
Installed 153 object(s) from 1 fixture(s)
3.1 Problems
Possible problems may arise when loading data because of how differently each database defines the schema and its requirements.
For example, common problems include how differently sqlite and
postgresql handle models.DateTime
fields, and the enforcement of
foreign keys uniqueness, etc.
If you get an IntegrityError message like:
django.db.utils.IntegrityError: Problem installing fixture 'local_datadump.json': Could not load contenttypes.ContentType(pk=3): duplicate key value violates unique constraint "django_content_type_app_label_model_XXXXXX_uniq"
DETAIL: Key (app_label, model)=(admin, logentry) already exists.
You should be sure the database is empty ./manage.py flush
or can
also dump the sqlite database using natural-foreign
keys, and
excluding contenttypes
and auth.permission
:
$ ./manage.py dumpdata --natural-foreign --exclude auth.permission --exclude contenttypes --indent 4 > data.json
3.1.1 Dumpdata Wagtaill
To dump a database containing a Wagtail app, further exclusions should
be considered or it would give errors like wagtail "psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint
:
./manage.py dumpdata --natural-foreign \
--exclude auth.permission --exclude contenttypes \
-e wagtailcore.groupcollectionpermission \
-e wagtailcore.grouppagepermission -e wagtailimages.rendition \
-e sessions \
--indent 4 > fixtures/local_datadump.json
Character varying Error
If you see something like: Could not load YOUR-MODEL(pk=1): value too long for type character varying(50)
it may be that SQLite didn’t
check the VARCHAR max_length
you have specified in your models
definitions, so you need to adjust or your data or the schema.
Many other kind of errors may (will) arise, that will need some tweaking, but after some adjustments you can enjoy your new PostgreSQL database.
References
- https://www.postgresql.org/docs/
- Management commands https://docs.djangoproject.com/en/3.1/ref/django-admin/
“SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured, SQL database engine” https://sqlite.org/index.html ↩︎
“PostgreSQL: The World’s Most Advanced Open Source Relational Database” https://www.postgresql.org/ ↩︎
https://docs.djangoproject.com/en/3.1/ref/django-admin/#dumpdata ↩︎
https://docs.djangoproject.com/en/3.1/ref/django-admin/#cmdoption-dumpdata-natural-foreign ↩︎
https://docs.djangoproject.com/en/3.1/ref/django-admin/#cmdoption-dumpdata-natural-primary ↩︎
https://docs.djangoproject.com/en/3.1/ref/django-admin/#what-s-a-fixture ↩︎
https://docs.djangoproject.com/en/3.1/ref/django-admin/#migrate ↩︎
https://docs.djangoproject.com/en/3.1/ref/django-admin/#loaddata ↩︎
- August 1, 2023
- How to create a reusable Django app and distribute it with PIP or publish to pypi.orgJune 29, 2021
- How To Serve Multiple Django Applications with uWSGI and Nginx in Ubuntu 20.04October 26, 2020
- How to add favicon to Django in 4 stepsSeptember 3, 2020
- Categories in Django with BreadcrumbsAugust 30, 2020
- How To Migrate From SQLite To PostgreSQL In Django In 3 steps
- Practical guide to internationalize a Django app in 5 steps.August 24, 2020
- Disable new users singup when using Django's allauth packageSeptember 3, 2019
- How to add ads.txt to Django as requested by Google AdsenseAugust 30, 2019
- Have multiple submit buttons for the same Django formJuly 2, 2019
- Better Testing with Page Object Design in DjangoMay 1, 2019
- Generating slugs automatically in Django without packages - Two easy and solid approachesFebruary 14, 2019
- How to set up Django tests to use a free PostgreSQL database in HerokuFebruary 13, 2019
- Dynamically adding forms to a Django FormSet with an add button using jQueryFebruary 6, 2019
- Use of Django's static templatetag in css file to set a background imageFebruary 1, 2019
- Activate Django's manage.py commands completion in Bash in 2 stepsJanuary 29, 2019
- Sending Emails with Django using SendGrid in 3 easy stepsJanuary 9, 2019
- Adding Users to Your Django Project With A Custom User ModelSeptember 21, 2018
- Setting Up A Factory For One To Many Relationships In FactoryboyApril 17, 2018
- Generate UML class diagrams from django modelsMarch 24, 2018
- Set Up Ubuntu To Serve A Django Website Step By StepJuly 3, 2017
- Django Project Directory StructureJuly 16, 2016
- How to Have Different Django Settings for Development and Production, and environment isolationJune 10, 2016
- Django OverviewJune 2, 2016
Django Forms
- Adding a Cancel button in Django class-based views, editing views and formsJuly 15, 2019
- Using Django Model Primary Key in Custom Forms THE RIGHT WAYJuly 13, 2019
- Django formset handling with class based views, custom errors and validationJuly 4, 2019
- How To Use Bootstrap 4 In Django FormsMay 25, 2018
- Understanding Django FormsApril 30, 2018
- How To Create A Form In DjangoJuly 29, 2016
Articles
Subcategories
Except as otherwise noted, the content of this page is licensed under CC BY-NC-ND 4.0 . Terms and Policy.
Powered by SimpleIT Hugo Theme
·