2017-10-21 151 views
1

J'ai un projet et j'ai défini mon module db.py comme:modèles de ballon 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() 

Puis-je importer db.db en modules qui ont besoin d'interroger la base de données et insérer des données (db. session.query()). Cependant, cela signifie que lorsque j'écris un code de test (pytest) pour tester un module qui importe db.py, je dois définir "SQLALCHEMY_DATABASE_URI". Une solution consiste à avoir un attribut paresseux pour que le code ci-dessus soit exécuté dans les tests uniquement si la base de données est utilisée/testée. Existe-t-il un modèle de conception courant pour Flask() + SQLA + SQLALCHEMY_DATABASE_URI là-bas que je manque? comment résoudrais-tu ce problème? Flask-config?

Répondre

1

La façon dont nous résolvons normalement ce problème est avec un application factory et une config.

Cela signifie que vous avez une fonction quelque part dans votre projet qui ressemble à ceci (extrait de la documentation avec des modifications):

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 

Ensuite (et nous espérons que vous utilisez pytest) dans votre répertoire de test racine , vous disposez d'un fichier conftest qui prépare automatiquement votre environnement de test quelque chose comme ceci:

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 

en règle générale, nous créons un autre appareil qui est également autouse=True qui gère cette installation DB, chasse d'eau, et Il est possible que vous chargiez des appareils et que vous utilisiez uniquement ce montage dans des tests nécessitant l'accès au DB (tests d'intégration ou fonctionnels), ce qui signifie simplement que nous incluons dans un fichier conftest le même répertoire que nos tests d'intégration.