5

I am starting with Django development as a hobby project. So far I have happily worked with SQLite, both in development (i.e. with py manage.py runserver) and in deployment (on Nginx + uWSGI). Now I would also like to learn to use a more robust PostgreSQL database. However, if possible, I would like to skip installing it locally, to avoid installing Postgres on Windows.

I was wondering if it was possible, by means of Django, to use SQLite whenever I use the built-in server and Postgres in deployment, without changing the project code. Couldn't find how to do it.

I can use a workaround and make my deployment procedure change the settings on server each time I deploy. But that's kind of a hack.

3
  • 1
    Just install PostgreSQL on your development machine. This way you can take production data and replicate and debug issues locally. Commented Nov 18, 2016 at 23:53
  • 1
    Using different stacks in development/testing and production is a bad idea. There are a lot of differences between databases that Django won't take care of for you so you're bound to run into problems in production that don't happen locally. Commented Nov 19, 2016 at 0:30
  • @mu_is_too_short, thanks for the heads up. My testing is also done on the server, so it has almost the same configuration as production. Also for this project the model is very simple, so I do hope Django will manage. I'll watch out for problems though and will switch as soon as possible. I am even thinking already of using SQLite for production, to keep things equivalent. Commented Nov 19, 2016 at 10:00

3 Answers 3

6

You could split your settings.py in multiple settings file e.g.

[projectname]/
├── [projectname]/
│   ├── __init__.py
│   ├── settings/
│   │   │── base.py
│   │   │── development.py
│   │   │── production.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

your base.py includes all code from your current settings.py. specify the different databases in your development.py(sqlite3) and in your production.py (postgresql) and import the base.py in each

from .base import *

Last but not least you'll have to tell django which file it should use. Add

export DJANGO_SETTINGS_MODULE="projectname.settings.development"

to your postactivate of your virtualenv on your development server and

export DJANGO_SETTINGS_MODULE="projectname.settings.production"

on your production server. Don't forget to

unset DJANGO_SETTINGS_MODULE

in your predeactivate.

More infos are here: http://www.marinamele.com/taskbuster-django-tutorial/settings-different-environments-version-control btw. a great tutorial with a lot of best practices

Sign up to request clarification or add additional context in comments.

Comments

4

replace settings.py with

 settings/
     │── __init__.py
     │── base.py
     │── development.py
     │── production.py

in __init__.py

import os

app_stage = os.environ.get('DJANGO_APP_STAGE', 'dev')
if app_stage == 'prod':
    from .production import *
else:
    from .development import *

And finally when you launch app for production, make sure you set env DJANGO_APP_STAGE='prod'

Create your database settings in respective files and you are good to go.

Comments

1

Very late reply, but I hope this helps someone in the future.

I found this article on Digital Ocean that has the database option split happening in one settings file. https://docs.digitalocean.com/tutorials/app-deploy-django-app/#configuring-database-access

Makes use of a DEVELOPMENT_MODE system environment variable to split settings. They also included a check to prevent a connection when a command is run like collectstatic.

settings.py file:

import os
import sys
import dj_database_url

DEVELOPMENT_MODE = os.getenv("DEVELOPMENT_MODE", "False") == "True"

if DEVELOPMENT_MODE is True:
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
        }
    }
elif len(sys.argv) > 0 and sys.argv[1] != 'collectstatic':
    if os.getenv("DATABASE_URL", None) is None:
        raise Exception("DATABASE_URL environment variable not defined")
    DATABASES = {
        "default": dj_database_url.parse(os.environ.get("DATABASE_URL")),
    }

Note: This is also making use of the Django Database URL package, but you could easily adapt for separated database arguments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.