我正在爲pytest配置一個夾具來創建瓶子應用程序實例。我的應用程序使用Application Factories pattern創建。我處於將其連接到數據庫的階段,並努力理解2種模式之間的差異。db.session.commit是否在Flask-SQLAlchemy中更改應用程序上下文?
# 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
在我的工裝夾具,我想我明白需要:安裝過程中
db.create_all()
:創建我的表db.drop_all()
拆卸過程中:測試db.session.remove()
拆卸過程中清洗乾淨後數據庫:在測試中經常敲擊數據庫時避免postgres上的一些奇怪的鎖
第一個設置(通過Miguel Grinberg book啓發)對我來說很有意義:
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:[email protected]: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()
中做的第一個燈具)。但如果我刪除它,它會失敗。
我無法重現您的問題。第二個裝置完全失敗,因爲你沒有推送應用程序上下文,而不是因爲你正在添加或刪除'db.session.commit()'。 – davidism