'How to specify a settings module when using the Django database shell command?

I'm trying to run the Django admin's dbshell command, but I'm having trouble specifying the settings module.

If I try to run it without defining any environment variable, I get an ImproperlyConfigured error suggesting I define a DJANGO_SETTINGS_MODULE:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ django-admin dbshell
Traceback (most recent call last):
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/bin/django-admin", line 11, in <module>
    sys.exit(execute_from_command_line())
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/core/management/base.py", line 322, in execute
    saved_locale = translation.get_language()
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/utils/translation/__init__.py", line 195, in get_language
    return _trans.get_language()
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/utils/translation/__init__.py", line 59, in __getattr__
    if settings.USE_I18N:
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/conf/__init__.py", line 56, in __getattr__
    self._setup(name)
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/conf/__init__.py", line 39, in _setup
    % (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting USE_I18N, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

My settings are located in lucy/settings/development.py, which I can import in a shell:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py shell
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import lucy.settings.development

In [2]: 

However, if I try to re-run the dbshell command with the DJANGO_SETTINGS_MODULE set to this dotted path, I get a ModuleNotFoundError:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ DJANGO_SETTINGS_MODULE=lucy.settings.development django-admin dbshell
Traceback (most recent call last):
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/bin/django-admin", line 11, in <module>
    sys.exit(execute_from_command_line())
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 308, in execute
    settings.INSTALLED_APPS
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/conf/__init__.py", line 56, in __getattr__
    self._setup(name)
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/conf/__init__.py", line 110, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 941, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 941, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'lucy'

How do I correctly specify the path of the revelant settings?



Solution 1:[1]

I was able to start the dbshell by using python manage.py instead of django-admin:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py dbshell
psql (10.3)
Type "help" for help.

lucy_prod=> 

Our manage.py actually contains some logic to set the DJANGO_SETTINGS_MODULE:

import os
import sys
from env import ENV_ROLE
from dotenv import load_dotenv, find_dotenv

if __name__ == "__main__":
    # allows setting environment type via environment variable
    # Handling Key Import Errors

    load_dotenv(find_dotenv())

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lucy.settings.%s" % ENV_ROLE)
    try:
        from django.core.management import execute_from_command_line
    except ImportError:
        # The above import may fail for some other reason. Ensure that the
        # issue is really that Django is missing to avoid masking other
        # exceptions on Python 2.
        try:
            import django  # noqa: F401
        except ImportError:
            raise ImportError(
                "Couldn't import Django. Are you sure it's installed and "
                "available on your PYTHONPATH environment variable? Did you "
                "forget to activate a virtual environment?"
            )
        raise
    execute_from_command_line(sys.argv)

The default ENV_ROLE is development.

Solution 2:[2]

Per https://stackoverflow.com/a/42068055/761963 (by @alasdair):

When you use django-admin, the directory containing mysite needs to be on the Python path for Django to be able to load mysite.settings.

Solution 3:[3]

You can manually specify the settings file with --settings:

lucy-web kurtpeek$ python manage.py dbshell --settings=lucy.settings.development

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kurt Peek
Solution 2 Jorge Orpinel Pérez
Solution 3