因此,为了提供上下文,应用程序启动后,应该在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()
后,仍会抛出上述错误。
我做得不好?
答案 0 :(得分:1)
您的FlaskMailService
类访问数据库,因此需要安装Flask应用程序上下文才能使用。如果没有应用程序上下文,Flask-SQLAlchemy就无法访问配置,这可以告诉它您的数据库位于何处。
解决此问题,将app
实例传递给后台作业,然后在运行服务任务之前创建应用程序上下文:
with app.app_context():
# do your db/mail things here