I'm trying to test my flask application using unittest. I want to refrain from flask-testing because I don't like to get ahead of myself.
I've really been struggling with this unittest thing now. It is confusing because there's the request context and the app context and I don't know which one I need to be in when I call db.create_all().
It seems like when I do add to the database, it adds my models to the database specified in my app module (init.py) file, but not the database specified in the setUp(self) method.
I have some methods that must populate the database before every test_ method.
How can I point my db to the right path?
#self.db_gd, app.config['DATABASE'] = tempfile.mkstemp()
app.config['TESTING'] = True
# app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE']
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + \
db = SQLAlchemy(app)
#self.app = app.test_client()
#self.app.testing = True
Here is one of the methods that populates my database:
new_user = User('Some User Name','[email protected]','admin')
new_user.role_id = 1
new_user.status = 1
new_user.password = generate_password_hash(new_user.password)
Places I've looked at:
And the flask documentation:
one issue that your hitting is the limitations of flask contexts, this is the primary reason i think long and hard before including a flask extension into my project, and flask-sqlalchemy is one of the biggest offenders. i say this because in most cases it is completely unnecessary to depend on the flask app context when dealing with your database. Sure it can be nice, especially since flask-sqlalchemy does a lot behind the scenes for you, mainly you dont have to manually manage your session, metadata or engine, but keeping that in mind those things can easily be done on your own, and for doing that you get the benefit of unrestricted access to your database, with no worry about the flask context. here is an example of how to setup your db manually, first i will show the flask-sqlalchemy way, then the manual plain sqlalchemy way:
import flask from flask_sqlalchemy import SQLAlchemy app = flask.Flask(__name__) db = SQLAlchemy(app) # define your models using db.Model as base class # and define columns using classes inside of db # ie: db.Column(db.String(255),nullable=False) # then create database db.create_all() # <-- gives error if not currently running flask app
the standard sqlalchemy way:
import flask import sqlalchemy as sa from sqlalchemy.ext.declarative import declarative_base # first we need our database engine for the connection engine = sa.create_engine(MY_DB_URL,echo=True) # the line above is part of the benefit of using flask-sqlalchemy, # it passes your database uri to this function using the config value # SQLALCHEMY_DATABASE_URI, but that config value is one reason we are # tied to the application context # now we need our session to create querys with Session = sa.orm.scoped_session(sa.orm.sessionmaker()) Session.configure(bind=engine) session = Session() # now we need a base class for our models to inherit from Model = declarative_base() # and we need to tie the engine to our base class Model.metadata.bind = engine # now define your models using Model as base class and # anything that would have come from db, ie: db.Column # will be in sa, ie: sa.Column # then when your ready, to create your db just call Model.metadata.create_all() # no flask context management needed now
if you set your app up like that, any context issues your having should go away.