Use in-memory database separately for testing - how? Use in-memory database separately for testing - how? flask flask

Use in-memory database separately for testing - how?


Sounds like the perfect case for inherited configurations!

Have you tried using the template found here? The Config base class contains settings that are common to all your different environments. But you can have a development environment that uses an in-memory database. For example:

class Config:  # passclass DevConfig(Config):  SQLALCHEMY_DATABASE_URI = 'sqlite://path_to_in_memory_db'class ProductionConfig(Config):  SQLALCHEMY_DATABASE_URI = 'postgresql://path_to_production_db'

It's also worth looking into using a factory pattern to create your app.


Okay, so I found a solution or rather a workaround:

I used an environment variable to specify an additional config file to be loaded before initializing the db instance.

So I ended up doing this:

app.config.from_object("app.config.production")additional_config = os.environ.get("ADDITIONAL_CONFIG")if additional_config:    app.config.from_object(additional_config)

in my my_app.py and this in my tests.py:

os.environ["ADDITIONAL_CONFIG"] = "app.config.testing"from my_app import app, db

(it is of course important to define the environment variable before importing the app object)

Thanks anyway.


I used environment variables to choose the db with pytest. This works well when using docker-compose to specify a production DB instead of sqllite for dev.

# app.pyBASE_DIR = os.path.abspath(os.path.dirname(__file__))DATABASE = os.environ.get("DB_URI", f"sqlite:///{os.path.join(BASE_DIR, 'app.db')}")app = Flask(__name__)app.config["SQLALCHEMY_DATABASE_URI"] = DATABASE

And then in test.py inject the DB_URI environment variable to specify a memory db before you import the app or db:

import pytestimport osos.environ['DB_URI'] = "sqlite:///:memory:"from app import app, dbfrom models import Model1, Model2@pytest.fixturedef client():    client = app.test_client()    with app.app_context():        db.create_all()        prepare_data()    yield client    db.drop_all()