-2

I bumped into the error when running python3 manage.py runserver.

I have mydb.py in the project's root directory (same as manage.py), in order to connect to MySQL and create a database (if it does not exist).

project    
│
└───todo
│   │   ...
│   │   settings.py
│   │   ...
│   
└───.env
└───mydb.py
└───...

mydb.py and settings.py share same database configuration which is loaded from environment variables in .env.

.env:

ENV=DEV
SECRET_KEY='django-insecure-9#1j%osjd33e'
DB_NAME=todolist
DB_USER=user
DB_PASSWORD=12345
DB_HOST=localhost
DB_PORT=3306

settings.py:

import os
from os.path import join, dirname
from dotenv import load_dotenv, find_dotenv

# (1)
ENV = os.environ.get('ENV')

if ENV == 'PROD':
    env_filename = '.env.prod'
elif ENV == 'TEST':
    env_filename = '.env.test'
# elif ENV == 'DEV':
#     env_filename = '.env.dev'
else:
    env_filename = '.env'

dotenv_path = join(dirname(__file__), env_filename)
load_dotenv(dotenv_path)

...

# Database
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': os.environ.get('DB_HOST'),
        'PORT': os.environ.get('DB_PORT'),
    }
}

...

mydb.py:

import mysql.connector

import os
from os.path import join, dirname
from dotenv import load_dotenv, find_dotenv

ENV = os.environ.get('ENV')

if ENV == 'PROD':
    env_filename = '.env.prod'
elif ENV == 'TEST':
    env_filename = '.env.test'
# elif ENV == 'DEV':
#     env_filename = '.env.dev'
else:
    env_filename = '.env'

dotenv_path = join(dirname(__file__), env_filename)
load_dotenv(dotenv_path)

dataBase = mysql.connector.connect(
    host = os.environ.get('DB_HOST'),
    user = os.environ.get('DB_USER'),
    passwd = os.environ.get('DB_PASSWORD'),
)

dataBase = mysql.connector.connect()
...

Problem:

I keep getting the following error, even though DB_HOST is already set in .env.

...
File "/home/user/django-test/.venv/lib/python3.10/site-packages/django/db/backends/mysql/base.py", line 218, in get_connection_params
    if settings_dict["HOST"].startswith("/"):
AttributeError: 'NoneType' object has no attribute 'startswith'

I have checked AttributeError: 'NoneType' object has no attribute 'startswith' while makemigrations with manage.py in django and some other related questions, but did not find any help.

Thank you

8
  • 1
    This suggests that os.environ.get('DB_HOST') returned None, because the dotenv loading somehow didn't do what you expected. Start with print(os.environ)…? Commented Jan 17, 2024 at 6:33
  • I tried my best to explain what I have encountered, including my own finding in other questions. Can't figure out the reason for downvotes (I literally did not copy-paste the whole codes, instead I just put relevant lines in the question). Feel free to point out unclear/missing points to summarize the question, which I should've done better Commented Jan 17, 2024 at 6:34
  • Did you try my suggestion above? Commented Jan 17, 2024 at 6:47
  • @deceze Sure, I did. It gave more or less like : os.environ: environ({..., 'VIRTUAL_ENV_PROMPT': '(.venv) ', ..., 'ENV': 'DEV', 'SECRET_KEY': 'django-insecure-9#1j%osjd33e', 'DB_NAME': 'todolist', 'DB_USER': 'user', 'DB_PASSWORD': '12345', 'DB_HOST': 'localhost', 'DB_PORT': '3306', 'TZ': 'UTC', 'RUN_MAIN': 'true'})'': Commented Jan 17, 2024 at 6:52
  • OK. So at the end of your settings file, does print(DATABASES) output the expected database config…? Commented Jan 17, 2024 at 6:53

1 Answer 1

1

The problem is likely this:

join(dirname(__file__), env_filename)

This is in todo/settings.py, so will look for todo/.env.

You need to go up one more directory.

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

3 Comments

This is in todo/settings.py, so will look for todo/.env. Thank you, this was the key!
Otherwise this is also possible without moving .env into the todo directory: dotenv_path = join(dirname(dirname(__file__)), '.env') (in code in the question)
But then your mydb.py breaks, and it's atypical to have .env files anywhere but in the root directory.

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.