db.create_all() 'NoneType' object has no attribute 'drivername'
Question:
I am following the CS50’s Web Programming with Python and Javascript and in Lecture4 I have had the following error trying to create a postgresql database table:
Traceback (most recent call last):
File "create.py", line 19, in <module>
main()
File "create.py", line 15, in main
db.create_all()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 963, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 955, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 896, in get_engine
return connector.get_engine()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 556, in get_engine
self._sa.apply_driver_hacks(self._app, info, options)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 830, in apply_driver_hacks
if info.drivername.startswith('mysql'):
AttributeError: 'NoneType' object has no attribute 'drivername'
The code that I have used is in two python file:
The first 1 called models.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Flight(db.Model):
__tablename__ = "flights"
id = db.Column(db.Integer, primary_key=True)
origin = db.Column(db.String, nullable=False)
destination = db.Column(db.String, nullable=False)
duration = db.Column(db.Integer, nullable=False)
class Passenger(db.Model):
__tablename__ = "passengers"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
flight_id = db.Column(db.Integer, db.ForeignKey("flight.id"), nullable=False)
The second file is called create.py:
import os
from flask import Flask, render_template, request
from models import *
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("postgresql://postgres:password@localhost/database1")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
def main():
db.create_all()
if __name__ == "__main__":
with app.app_context():
main()
Can you help me?!
Answers:
Check line os.getenv("postgresql://postgres:password@localhost/database1")
It doesn’t contain the name of the environment variable.
Reference: https://docs.python.org/3/library/os.html?highlight=getenv#os.getenv
Sample usage:
$ python
Python 3.7.0 (default, Aug 20 2018, 15:06:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> editor = os.getenv('EDITOR')
>>> print(editor)
vi
To clarify gbajson’s answer, os.getenv
gets a value from a specific environment variable. You either need to store the database URI in an env var (before you start Flask) and get it from there:
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URI")
or, hard code it directly as a string without using getenv:
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:password@localhost/database1"
I think this is an issue with how you’re attempting to connect to your Postgres
database:
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("postgresql://postgres:password@localhost/database1")
you probably want this line to be the following instead:
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:password@localhost/database1"
since the os.getenv(...)
is currently trying to get an environment variable on your system named: "postgresql://postgres:password@localhost/database1"
and you surely didn’t set up an environment variable with this name.. Which is why you’re getting a NoneType
error for your postgres
driver:
AttributeError: ‘NoneType’ object has no attribute ‘drivername’.
If you want to use an environment variable to get your database connection string, do something like the following in your .bash_profile
or .bashrc
file:
export SQLALCHEMY_DATABASE_URI='postgresql://postgres:password@localhost/database1'
then change your database connection code to the following:
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get('SQLALCHEMY_DATABASE_URI')
Hopefully that makes sense!
I am creating web application blog based on Flask, which is connecting to database via SQLAlchemy module.
When running application on server, I got AttributeError: 'NoneType' object has no attribute 'drivername'
, which brought me here.
What I had as environment attributes before (locally in development), now I have as config.json
file for production.
To access that, I use:
with open('path/to/config.json') as config_file:
and then save that configuration as python dictionary in variable with config = json.load(config_file)
.
I named my sql variable exactly like this:
SQLALCHEMY_DATABASE_URI = config.get('SQLALCHEMY_DATABASE_URI')
I named it exactly the same way in my config.json file to which it goes.
I was looking for a problem withing packages installed in my virtual environment but that didn’t help. What was the problem is that I made a typo, calling my json key "SQALCHEMY_DATABASE_URI" inside my config.json, missing "L". This type of dumb typo got me exactly same error, making me spend too much time on that, so perhaps if someone is looking for a similar solution, double check your syntax/spelling first.
Cheers!
Succinctly: this can be caused by SQLALCHEMY_DATABASE_URI not being set.
I am following the CS50’s Web Programming with Python and Javascript and in Lecture4 I have had the following error trying to create a postgresql database table:
Traceback (most recent call last):
File "create.py", line 19, in <module>
main()
File "create.py", line 15, in main
db.create_all()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 963, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 955, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 896, in get_engine
return connector.get_engine()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 556, in get_engine
self._sa.apply_driver_hacks(self._app, info, options)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 830, in apply_driver_hacks
if info.drivername.startswith('mysql'):
AttributeError: 'NoneType' object has no attribute 'drivername'
The code that I have used is in two python file:
The first 1 called models.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Flight(db.Model):
__tablename__ = "flights"
id = db.Column(db.Integer, primary_key=True)
origin = db.Column(db.String, nullable=False)
destination = db.Column(db.String, nullable=False)
duration = db.Column(db.Integer, nullable=False)
class Passenger(db.Model):
__tablename__ = "passengers"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
flight_id = db.Column(db.Integer, db.ForeignKey("flight.id"), nullable=False)
The second file is called create.py:
import os
from flask import Flask, render_template, request
from models import *
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("postgresql://postgres:password@localhost/database1")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
def main():
db.create_all()
if __name__ == "__main__":
with app.app_context():
main()
Can you help me?!
Check line os.getenv("postgresql://postgres:password@localhost/database1")
It doesn’t contain the name of the environment variable.
Reference: https://docs.python.org/3/library/os.html?highlight=getenv#os.getenv
Sample usage:
$ python
Python 3.7.0 (default, Aug 20 2018, 15:06:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> editor = os.getenv('EDITOR')
>>> print(editor)
vi
To clarify gbajson’s answer, os.getenv
gets a value from a specific environment variable. You either need to store the database URI in an env var (before you start Flask) and get it from there:
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URI")
or, hard code it directly as a string without using getenv:
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:password@localhost/database1"
I think this is an issue with how you’re attempting to connect to your Postgres
database:
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("postgresql://postgres:password@localhost/database1")
you probably want this line to be the following instead:
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:password@localhost/database1"
since the os.getenv(...)
is currently trying to get an environment variable on your system named: "postgresql://postgres:password@localhost/database1"
and you surely didn’t set up an environment variable with this name.. Which is why you’re getting a NoneType
error for your postgres
driver:
AttributeError: ‘NoneType’ object has no attribute ‘drivername’.
If you want to use an environment variable to get your database connection string, do something like the following in your .bash_profile
or .bashrc
file:
export SQLALCHEMY_DATABASE_URI='postgresql://postgres:password@localhost/database1'
then change your database connection code to the following:
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get('SQLALCHEMY_DATABASE_URI')
Hopefully that makes sense!
I am creating web application blog based on Flask, which is connecting to database via SQLAlchemy module.
When running application on server, I got AttributeError: 'NoneType' object has no attribute 'drivername'
, which brought me here.
What I had as environment attributes before (locally in development), now I have as config.json
file for production.
To access that, I use:
with open('path/to/config.json') as config_file:
and then save that configuration as python dictionary in variable with config = json.load(config_file)
.
I named my sql variable exactly like this:
SQLALCHEMY_DATABASE_URI = config.get('SQLALCHEMY_DATABASE_URI')
I named it exactly the same way in my config.json file to which it goes.
I was looking for a problem withing packages installed in my virtual environment but that didn’t help. What was the problem is that I made a typo, calling my json key "SQALCHEMY_DATABASE_URI" inside my config.json, missing "L". This type of dumb typo got me exactly same error, making me spend too much time on that, so perhaps if someone is looking for a similar solution, double check your syntax/spelling first.
Cheers!
Succinctly: this can be caused by SQLALCHEMY_DATABASE_URI not being set.