pytest-flask-sqlalchemy icon indicating copy to clipboard operation
pytest-flask-sqlalchemy copied to clipboard

issues with using the application factory pattern

Open sebastianelsner opened this issue 4 years ago • 1 comments

I am using the application factory pattern as described in the flask docs: https://flask.palletsprojects.com/en/1.1.x/patterns/appfactories/ , e.g.:

def create_app():
    app = Flask(__name__)

    from yourapplication.model import db
    db.init_app(app)

As described in the docs here, I would then do:


from yourapplication.model import db

@pytest.fixture(scope="session")
def app():
    app = create_app()
    return app

@pytest.fixture(scope="session")
def _db(app):
    db.init_app(app)
    return db

but this leads to a "RuntimeError: No application found...." in my test

_______________________ ERROR at setup of test_set_name ________________________

request = <SubRequest '_transaction' for <Function test_set_name>>
_db = <SQLAlchemy engine=None>
mocker = <pytest_mock.plugin.MockFixture object at 0x7f98a6919be0>

    @pytest.fixture(scope='function')
    def _transaction(request, _db, mocker):
        '''
        Create a transactional context for tests to run in.
        '''
        # Start a transaction
>       connection = _db.engine.connect()

.venv/lib64/python3.8/site-packages/pytest_flask_sqlalchemy/fixtures.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib64/python3.8/site-packages/flask_sqlalchemy/__init__.py:943: in engine
    return self.get_engine()
.venv/lib64/python3.8/site-packages/flask_sqlalchemy/__init__.py:952: in get_engine
    app = self.get_app(app)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <SQLAlchemy engine=None>, reference_app = None

    def get_app(self, reference_app=None):
        """Helper method that implements the logic to look up an
        application."""
    
        if reference_app is not None:
            return reference_app
    
        if current_app:
            return current_app._get_current_object()
    
        if self.app is not None:
            return self.app
    
>       raise RuntimeError(
            'No application found. Either work inside a view function or push'
            ' an application context. See'
            ' http://flask-sqlalchemy.pocoo.org/contexts/.'
        )
E       RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.

.venv/lib64/python3.8/site-packages/flask_sqlalchemy/__init__.py:987: RuntimeError

This also gives the same error:

@pytest.fixture(scope="session")
def _db(app):
    db = SQLAlchemy()
    db.init_app(app)
    return db

But this works:

@pytest.fixture(scope="session")
def _db(app):
    db = SQLAlchemy(app=app)
    db.init_app(app) 
    return db

The "db.init_app(app)" is double, but it shows, that this statement does not acutally do something bad.

How do I correctly use this and why is the "init_app" different?

sebastianelsner avatar Jul 17 '20 10:07 sebastianelsner

I have the same problem. But for me even the solution presented by @sebastianelsner does not work.

tytuseczek avatar Dec 01 '21 11:12 tytuseczek