Does db.session.commit application context change in Flask-SQLAlchemy?

I am setting up an instrument for pytest that creates an instance of the flash application. My application is created with Application Factory Templates . I am at the stage of connecting to the database and trying to understand the difference between the two templates.

# project/__init__.py
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()


def create_app():
    app = Flask(__name__)

    app_settings = os.getenv('APP_SETTINGS')
    app.config.from_object(app_settings)

    db.init_app(app)

    [blueprint code]

    return app

In my device, I think I understand the need:

  • db.create_all() during installation: create my tables
  • db.drop_all() during break: clean database after tests
  • db.session.remove() during break: avoid some weird postgres locks when the database gets hit in tests often

The first setup (inspired by Miguel Greenberg 's book ) makes sense to me:

import pytest
from project import create_app, db


@pytest.fixture
def app():
    app = create_app()
    with app.app_context():
        db.create_all()
        yield app
        db.session.remove()
        db.drop_all()

, , / app_context :

Python 3.6.1 (default, Jun 21 2017, 18:45:41) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from project import create_app, db
>>> app = create_app()
>>> db
<SQLAlchemy engine=None>
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> db.create_all()
>>> db
<SQLAlchemy engine='postgres://postgres:postgres@users-db:5432/users_dev'>

( testdriven.io) pytest, , :

import pytest
from project import create_app, db


@pytest.fixture
def app():
    app = create_app()
    db.create_all()
    db.session.commit()  # fail when this is removed
    yield app
    db.session.remove()
    db.drop_all()

, , :

Python 3.6.1 (default, Jun 21 2017, 18:45:41) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from project import create_app, db
>>> app = create_app()
>>> db.create_all()
[...] timeError: application not registered on db instance and no application bound to current context

db.session.commit(), , , , ( , with app_context() ). , .

+4
1

, ( testdriven.io) Application Factory, db (, db = SQLAlchemy(app) db = SQLAlchemy() db.init(app) create_app()). Application Factory, , db.create_all(), / db.session.commit() .

, from project import create_app, db Application Factory .

.

1) db.create_all() Application Factory?

__init__ SQLAlchemy, , , SQLAlchemy, self.app = app. , Application Factory, , db.init_app(app). create_all(), app, , , get_app, reference_app, None, current_app > , Flask (. from flask import current_app), , None, , , , self.app, None, Application Factory, application not registered on db instance and no application bound to current context.

2) db.session.commit() db.create_all SQLAlchemy (, db = SQLAlchemy(app))? **

, , , , testdriven.io. db.session.commit(), Application Factory SQLAlchemy (, db = SQLAlchemy(app)) , create_all(app) .

import pytest
import os
import datetime
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

db = SQLAlchemy(app)


@pytest.fixture
def app():
    app = create_app()
    db.create_all()
    # db.session.commit()  # Try this with and without this line
    yield app
    db.session.remove()
    db.drop_all()

:

https://github.com/mitsuhiko/flask-sqlalchemy/blob/d71afea650e0186348d81f02cca5181ed7c466e9/flask_sqlalchemy/ init.py

http://flask-sqlalchemy.pocoo.org/2.1/contexts/

+6

Source: https://habr.com/ru/post/1680707/


All Articles