当我在烧瓶上启动应用程序时,抛出“RuntimeError”。下面是我失败的代码

时间:2018-03-02 19:57:51

标签: python-3.x flask-sqlalchemy

因此,为了提供上下文,应用程序启动后,应该在5秒后发送邮件。但是当我启动应用程序时,会抛出错误。以下是错误:

(learning_map_api) Eloka-Chima:learning_map_api andeladeveloper$ 
gunicorn main:app --worker-class gevent
[2018-03-03 10:02:48 +0100] [60007] [INFO] Starting gunicorn 19.7.1
[2018-03-03 10:02:48 +0100] [60007] [INFO] Listening at: 
http://127.0.0.1:8000 (60007)
[2018-03-03 10:02:48 +0100] [60007] [INFO] Using worker: gevent
[2018-03-03 10:02:48 +0100] [60010] [INFO] Booting worker with pid: 
60010
Job "<lambda> (trigger: interval[0:00:05], next run at: 2018-03-03 
10:02:50 WAT)" raised an exception
Traceback (most recent call last):
 File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/sqlalchemy/util/_collections.py", line 988, in __call__
return self.registry[key]
KeyError: <Greenlet at 0x10f1c6638: <bound method Thread._bootstrap of 
<Thread(ThreadPoolExecutor-1_0, started daemon 4548486712)>>>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/apscheduler/executors/base.py", line 125, in run_job
retval = job.func(*job.args, **job.kwargs)
File "/Users/andeladeveloper/Desktop/learning_map_api/main.py", line 228, in <lambda>
scheduler.add_job(lambda: FlaskMailService().send_mail(email),
File "/Users/andeladeveloper/Desktop/learning_map_api/api/core/services/email_service/flask_mail_service.py", line 39, in send_mail
self.content = self.__notification_template()
File "/Users/andeladeveloper/Desktop/learning_map_api/api/core/services/email_service/flask_mail_service.py", line 55, in __notification_template
_contributions = Contribution.query.order_by(
File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 498, in __get__
return type.query_class(mapper, session=self.sa.session())
File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/sqlalchemy/orm/scoping.py", line 78, in __call__
return self.registry()
File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/sqlalchemy/util/_collections.py", line 990, in __call__
return self.registry.setdefault(key, self.createfunc())
File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 2867, in __call__
return self.class_(**local_kw)
File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 143, in __init__
self.app = app = db.get_app()
File "/Users/andeladeveloper/.virtualenvs/learning_map_api/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 957, in get_app
'application not registered on db instance and no application'
RuntimeError: application not registered on db instance and no applicationbound to current context

下面我创建了一个处理Flask app:

实例创建的方法
def create_flask_app(environment):
    app = Flask(__name__, instance_relative_config=True, static_folder=None)
    app.config.from_object(app_configuration[environment])

    CORS(app)

    # initialize SQLAlchemy
    models.db.init_app(app)

    # initilize migration commands
    Migrate(app, models.db)

    # initilize api resources
    api = Api(app)

以下是我使用with app.app_context()为其提供应用程序的上下文所做的工作:

def create_flask_app(environment):
    app = Flask(__name__, instance_relative_config=True, static_folder=None)
    app.config.from_object(app_configuration[environment])
    with app.app_context():
        CORS(app)

        # initialize SQLAlchemy
        models.db.init_app(app)

        # initilize migration commands
        Migrate(app, models.db)

        # initilize api resources
        api = Api(app)

以下是调用方法的地方:

app = create_flask_app(os.getenv("FLASK_CONFIG") or "development")
ADMIN_SENDER = os.environ.get('ADMIN_SENDER')
recipients = [
    'my-app@gmail.com',
]
email = {
    'config': app,
    'subj': "Notification",
    'from': ADMIN_SENDER,
    'to': recipients,
    'contrib_title': None
}
scheduler.add_job(lambda: FlaskMailService().send_mail(email),
              'interval', seconds=5, id='send_mail',
              start_date='2017-11-16 23:30:00',
              timezone="Africa/Lagos")
atexit.register(lambda: scheduler.shutdown(wait=False))
scheduler.start()

尝试使用with app.app_context()后,仍会抛出上述错误。 我做得不好?

1 个答案:

答案 0 :(得分:1)

您的FlaskMailService类访问数据库,因此需要安装Flask应用程序上下文才能使用。如果没有应用程序上下文,Flask-SQLAlchemy就无法访问配置,这可以告诉它您的数据库位于何处。

解决此问题,将app实例传递给后台作业,然后在运行服务任务之前创建应用程序上下文:

with app.app_context():
    # do your db/mail things here