How do you set up a Flask application with SQLAlchemy for testing?

前端 未结 3 1713
遇见更好的自我
遇见更好的自我 2020-12-24 12:47

It seems common practice in Flask to start like this:

from flask import Flask
from flaskext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
SQLALCHEMY_DAT         


        
3条回答
  •  心在旅途
    2020-12-24 13:16

    Your instinct to use environment variables is correct. However, there is some danger of running unit tests with the wrong db. Also, you may not want to connect_db with every request and everywhere you want to use db. You can use a config directory and environment variables which you set explicitly. This is the best I've come up with so far.

    run.py
    shell.py
    
    config/__init__.py
    config/test.py
    config/postgres.py
    ...
    
    main/__init__.py
    main/someapp/__init__.py
    main/someapp/models.py
    
    ...
    main/tests/__init__.py
    main/tests/testutils.py
    

    so, the config files may be:

    # config/test.py
    SQLALCHEMY_DATABASE_URI = "sqlite://"
    

    and

    # config/postgres.py
    SQLALCHEMY_DATABASE_URI = 'postgresql://user:pw@localhost/somedb'
    

    So, I can explicitly set the db in my base TestCase:

    import os
    from flask.ext.testing import TestCase
    
    os.environ["DIAG_CONFIG_MODULE"] = "config.test"
    from main import app, db
    
    
    class SQLAlchemyTest(TestCase):
    
        def create_app(self):
            return app
    
        def setUp(self):
            db.create_all()
    
        def tearDown(self):
            db.session.remove()
            db.drop_all()
    

    Then, the main/__init__.py, for me:

    import os
    
    from flask import Flask, render_template, g
    from flask.ext.sqlalchemy import SQLAlchemy
    
    # by default, let's use a DB we don't care about
    # but, we can override if we want
    config_obj = os.environ.get("DIAG_CONFIG_MODULE", "config.test")
    app = Flask(__name__)
    app.config.from_object(config_obj)
    db = SQLAlchemy(app)
    
    @app.before_request
    def before_request():
        g.db = db
        g.app = app
    
    # ...
    @app.route('/', methods=['GET'])
    def get():
        return render_template('home.html')
    # ...    
    from main.someapp.api import mod as someappmod
    app.register_blueprint(someappmod)
    

    Then, in the other files, where I know what config I want to run, potentially:

    # run.py
    import os
    os.environ["DIAG_CONFIG_MODULE"] = "config.postgres"
    from main import app
    app.run(debug=True)
    

    and

    # shell.py
    import os
    os.environ["DIAG_CONFIG_MODULE"] = "config.postgres"
    
    from main import app, db
    from main.symdiag.models import *
    from main.auth.models import *
    print sorted(k for k in locals().keys() if not k.startswith("_"))
    import IPython
    IPython.embed()
    

    Maybe .. best so far :P.

提交回复
热议问题