Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible with flask-sqlalchemy-3.0 #63

Open
stabacco opened this issue Oct 11, 2022 · 6 comments
Open

Incompatible with flask-sqlalchemy-3.0 #63

stabacco opened this issue Oct 11, 2022 · 6 comments

Comments

@stabacco
Copy link

stabacco commented Oct 11, 2022

Looks like there has been a new major release for flask-sqlalchemy https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/changes/#version-3-0-0 and they have broken backwards compatibility in a few places.

For example :

    @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()

../../../.cache/pypoetry/virtualenvs/api-S2mtXI53-py3.8/lib/python3.8/site-packages/pytest_flask_sqlalchemy/fixtures.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../.cache/pypoetry/virtualenvs/api-S2mtXI53-py3.8/lib/python3.8/site-packages/flask_sqlalchemy/extension.py:642: in engine
    return self.engines[None]
../../../.cache/pypoetry/virtualenvs/api-S2mtXI53-py3.8/lib/python3.8/site-packages/flask_sqlalchemy/extension.py:628: in engines
    app = current_app._get_current_object()  # type: ignore[attr-defined]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    def _get_current_object() -> T:
        try:
            obj = local.get()  # type: ignore[union-attr]
        except LookupError:
>           raise RuntimeError(unbound_message) from None
E           RuntimeError: Working outside of application context.
E           

Also the create_scoped_session method seems to have gone.

@zoltan-fedor
Copy link

Yeap, create_scoped_session method has been replaced by _make_scoped_session, see https://github.com/pallets-eco/flask-sqlalchemy/blob/2908083d0d0c918e1adce396d351da6fa3112692/src/flask_sqlalchemy/extension.py#L336, so that would need to be updated to that.

@Midnighter
Copy link

I believe a solution is to use SQLAlchemy directly:

from sqlalchemy.orm import sessionmaker, scoped_session

db.session = scoped_session(session_factory=sessionmaker(bind=db_connection))

@pamelafox
Copy link

Thanks @Midnighter ! If folks are looking for a workaround for now, this is the conftest.py I'm using with latest flask-sqlalchemy for similar purposes - not as comprehensive as this package, but works for a fake session:

https://github.com/pamelafox/flask-surveys-container-app/blob/main/backend/tests/conftest.py

@davidism
Copy link

davidism commented Feb 28, 2023

I'm not sure exactly how this library works, but the way config, engines, and the session are managed did change significantly in Flask-SQLAlchemy 3.0. Just monkeypatching db.session as suggested above might work for simple cases, but I have a feeling it will fail in weird ways.

The following code sets up transactions for each bind, then rolls them back after each test. This supports multiple binds, in case one request queries multiple databases.

@pytest.fixture
def db(app):
    with app.app_context():
        engines = db.engines

    cleanup = []

    for key, engine in engines.items():
        c = engine.connect()
        t = c.begin()
        engines[key] = c
        cleanup.append((key, engine, c, t))

    yield db

    for key, engine, c, t in cleanup:
        t.rollback()
        c.close()
        engines[key] = engine

ntarocco added a commit to ntarocco/pytest-invenio that referenced this issue Apr 12, 2023
* replaces the previous not private method `create_scoped_session`
  with the private method `_make_scoped_session`. Related GitHub issue:
  jeancochrane/pytest-flask-sqlalchemy#63
ntarocco added a commit to ntarocco/pytest-invenio that referenced this issue Apr 12, 2023
* replaces the previous public method `create_scoped_session` from
  flask-sqlalchemy with the direct way of creating a new session with
  SQLAlchemy. Related GitHub issue:
  jeancochrane/pytest-flask-sqlalchemy#63
ntarocco added a commit to ntarocco/pytest-invenio that referenced this issue Apr 12, 2023
* replaces the previous public method `create_scoped_session` from
  flask-sqlalchemy with the direct way of creating a new session with
  SQLAlchemy. Related GitHub issue:
  jeancochrane/pytest-flask-sqlalchemy#63
ntarocco added a commit to ntarocco/pytest-invenio that referenced this issue Apr 12, 2023
* replaces the previous public method `create_scoped_session` from
  flask-sqlalchemy with the direct way of creating a new session with
  SQLAlchemy. Related GitHub issue:
  jeancochrane/pytest-flask-sqlalchemy#63
kpsherva pushed a commit to inveniosoftware/pytest-invenio that referenced this issue Apr 13, 2023
* replaces the previous public method `create_scoped_session` from
  flask-sqlalchemy with the direct way of creating a new session with
  SQLAlchemy. Related GitHub issue:
  jeancochrane/pytest-flask-sqlalchemy#63
@jasondoong
Copy link

I'm not sure if this works in more complex situations, but it works in my project.
Teachesworkspace@d6ae3d9

@gmassman
Copy link

gmassman commented Jan 5, 2024

If anyone was like me and had problems migrating pytest from SQLAlchemy <= 1.4 to SQLAlchemy 2.0, I created a minimum working example and was able to backtrack through my own test suite to find out why transactional tests weren't working.

https://github.com/gmassman/fsa-rollback-per-test-example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants