1
votes

I am getting "AttributeError: 'NoneType' object has no attribute 'drivername'" when trying to connect to an existing empty PostgreSQL db on localhost from Flask app.

Here's .env:

...
SQLALCHEMY_DATABASE_URI='postgresql+psycopg2://postgres:PASSWORD@localhost/DATABASE' 
...

Here's config:

import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Config(object):
    DEBUG = False
    TESTING = False
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class ProdConfig(Config):
    DEBUG = False

class StagingConfig(Config):
    DEVELOPMENT = True
    DEBUG = True

class DevConfig(Config):
    DEVELOPMENT = True
    DEBUG = True

class TestConfig(Config):
    TESTING = True

Here's app.extensions:

from flask_sqlalchemy import SQLAlchemy

db=SQLAlchemy()
...

And here's __init__:

from flask import Flask, Blueprint...
from . config import Config
from flask_login import LoginManager
from flask_migrate import Migrate
from pathlib import Path

login_manager = LoginManager()
login_manager.login_view = 'auth.login'

def create_app():
    app = Flask(__name__,
                static_url_path='',
                static_folder='../app/static',
                template_folder='../app/templates')

    app.config.from_object(Config)

    from .extensions import db
    db.init_app(app)

    Migrate(app, db)
    
    from .templates.auth import auth_bp
    from .views.main import main_bp

    app.register_blueprint(main_bp)
    app.register_blueprint(auth_bp, url_prefix='/auth')

    login_manager.init_app(app)

    return app

I've checked the following Stackoverflow answers:

db.create_all() 'NoneType' object has no attribute 'drivername',

SQLAlchemy: 'NoneType' object has no attribute 'drivername',

SQLAlchemy cannot connect to Postgresql on localhost,

Flask app gives a " 'NoneType' object has no attribute 'drivername' " error

and all of them seem to point to errors in SQLALCHEMY_DATABASE_URI declaration.

This doesn't solve my problem. I have tried

>>> from app.extensions import db
>>> db.create_all()

and

>>> from app import create_app 
>>> app = create_app()
>>> from app.extensions import db
>>> db.create_all()

and

>>> from app import create_app
>>> app=create_app()
>>> app.app_context().push() 
>>> from app.extensions import db
>>> db.create_all()

The results are the same.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\...\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1039, in create_all
    self._execute_for_all_tables(app, bind, 'create_all')
  File "C:\Users\...\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1031, in _execute_for_all_tables        
    op(bind=self.get_engine(app, bind), **extra)
  File "C:\Users\...\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 962, in get_engine
    return connector.get_engine()
  File "C:\Users\...\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 555, in get_engine
    options = self.get_options(sa_url, echo)
  File "C:\Users\...\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 570, in get_options
    self._sa.apply_driver_hacks(self._app, sa_url, options)
  File "C:\Users\...\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 883, in apply_driver_hacks
    if sa_url.drivername.startswith('mysql'):
AttributeError: 'NoneType' object has no attribute 'drivername'

Any help will be greatly appreciated.

1
I would check that the environment variable SQLALCHEMY_DATABASE_URI is definitely being set, for example by printing/logging its value.snakecharmerb
Is python-dotenv installed? Otherwise Flask doesn’t support .env files.rfkortekaas
Can you try from dotenv import load_dotenv then load_dotenv() and then os.getenv('SQLALCHEMY_DATABASE_URI')?rfkortekaas
>>> load_dotenv() Python-dotenv could not parse statement starting at line 2 True >>>grommit
Can you add your complete .env file. The mistake is somewhere in that file! Please make sure to remove sensitive data but keep the structure and names!rfkortekaas

1 Answers

0
votes

Solved by @rfkortekaas:

>>> from dotenv import load_dotenv
>>> load_dotenv()
>>> import os
>>> os.getenv('SQLALCHEMY_DATABASE_URI')
>>> from app import create_app
>>> app = create_app()
>>> app.app_context().push()   
>>> from app.extensions import db
>>> db.create_all()