jeancochrane / jeancochrane/pytest-flask-sqlalchemy

issues with using the application factory pattern

Open
#32 1 comment 3 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
253
Forks
45
PR merge metrics
No merged PRs in 30d

Description

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.:

```python
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:

```python

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 = >
_db =
mocker =

@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 = , 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?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the _transaction and _db fixtures shown in the traceback, then compare SQLAlchemy(app=app) with db.init_app(app) and inspect how Flask-SQLAlchemy resolves the application. Reproduce the failure with the application factory and verify the correct fixture setup; done means the transactional fixture runs without the application-context error and the difference is explained.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, python, sqlalchemy
Domain
database, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.