Search code examples
sqlalchemyflask-sqlalchemyflask-testing

Import reflected Flask-SQLAlchemy Module before creating the app


This is a continuation of this question.

As my flask app should not write anything in my database, I set up Flask-SQLAlchemy to reflect my database. This way I do not have to change my models, when I change my schema:

# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    db.init_app(app)
    with app.app_context():
        db.Model.metadata.reflect(db.engine)
# app/models.py
from app import db

class Data(db.Model):
    __table__ = db.Model.metadata.tables['data']

But now, if I have to import the Model before I created the app, I run into Errors because the metadata is not set yet. This is a problem when it comes to testing for example:

# test.py
import unittest
from app import create_app, db
from app.models import Data


class TestGUI(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.app = create_app()
# etc ...

This throws KeyError: 'data' in __table__ = db.Model.metadata.tables['data'] when importing from app.models as the metadata is not correctly set before the create_app() function is run.


Solution

  • I did find a solution (thanks to @snakecharmerb). The solution is simply to avoid the problem, to not import app.models before running create_app(). A bit hacky, so feel free to post an answer as well, when you have a better solution. My test file now looks like this:

    # test.py
    import unittest
    from app import create_app, db
    app = create_app()
    from app.models import Data
    
    
    class TestGUI(unittest.TestCase):
        @classmethod
        def setUpClass(cls):
            cls.app = app
    # etc ...