2017-10-21 9 views
1

私はプロジェクトを持っていると私は私のdb.pyモジュールを定義しました:PythonのSQLAlchemyのフラスコパターン

app = get_global_flask_app() 
app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://foo:[email protected]:5432/test" 
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 
db = SQLAlchemy(app) 
db.create_all() 

それから私は、DB(データベースを照会し、データを挿入する必要があるモジュールにdb.dbをインポートします。 session.query())。

しかし、これは、db.pyをインポートするモジュールをテストするためのテストコード(pytest)を書くときに、 "SQLALCHEMY_DATABASE_URI"を定義する必要があることを意味します。 1つの解決策は、上記のコードがデータベースが使用/テストされた場合にのみテストで実行されるように、dbを遅延属性にすることです。 Flask()+ SQLA + SQLALCHEMY_DATABASE_URIの共通のデザインパターンがありますか?どのようにこの問題を解決しますか?フラスコの設定?

答えて

1

私たちが通常この問題を解決する方法は、application factoryとconfigです。あなたのルートのテストディレクトリに続いて

def create_app(config_filename, settings_override=None): 
    app = Flask(__name__) 
    app.config.from_pyfile(config_filename) 
    app.config.from_object(settings_override) 

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

    from yourapplication.views.admin import admin 
    from yourapplication.views.frontend import frontend 
    app.register_blueprint(admin) 
    app.register_blueprint(frontend) 

    return app 

(そして、できれば使用しているpytest):

これは、あなたが(修正をドキュメントから引用)このようになり、プロジェクトのどこかの機能を持っていることを意味します、あなたは自動的にあなたのテスト環境は、このような何か準備conftestファイルがあります:

import pytest 
from your_project import create_app 


class TestConfig: 
    SQLALCHEMY_DATABASE_URI = "postgresql://foo:[email protected]:5432/test" 
    SQLALCHEMY_TRACK_MODIFICATIONS = False 
    ANY OTHER SETTINGS... 


@pytest.fixture(autouse=True) 
def app(request): 
    app = create_app(settings_override=TestConfig) 
    ctx = app.app_context() 
    ctx.push() 

    def teardown(): 
     ctx.pop() 

    request.addfinalizer(teardown) 

    return app 

一般的に、我々はそのDBセットアップ、フラッシュを扱うもautouse=Trueで別のフィクスチャを作成して、 DB(統合テストまたは機能テスト)にアクセスする必要のあるテストでのみフィクスチャを使用します。つまり、インテグレーションテストと同じディレクトリにあるconftestファイルに含めるだけです。