我已经尝试过这项工作,但必须有更好的方法,欢迎任何意见。
我尝试使用pyramid_mailer(存储在.ini文件中的设置)在我的python金字塔应用中发送预定的电子邮件,并使用apscheduler来设置时间表。
我还使用SQLAlchemyJobStore,因此如果应用重新启动,可以重新启动作业。
jobstores = {
'default': SQLAlchemyJobStore(url='mysql://localhost/lgmim')
}
scheduler = BackgroundScheduler(jobstores=jobstores)
@view_config(route_name='start_email_schedule')
def start_email_schedule(request):
# add the job and start the scheduler
scheduler.add_job(send_scheduled_email, 'interval', [request], weeks=1)
scheduler.start()
return HTTPOk()
def send_scheduled_email(request):
# compile message and recipients
# send mail
send_mail(request, subject, recipients, message)
def send_mail(request, subject, recipients, body):
mailer = request.registry['mailer']
message = Message(subject=subject,
recipients=recipients,
body=body)
mailer.send_immediately(message, fail_silently=False)
就我而言,现在我收到了错误,大概是因为它无法剔除请求。
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
使用pyramid.threadlocal.get_current_registry().settings
第一次使邮件工作,但此后我收到错误。我建议不要在任何情况下使用它。
我还能做什么?
答案 0 :(得分:2)
通常,你不能挑选request
对象,因为它包含对开放套接字和其他活泼对象之类的引用。
这里有一些有用的模式
您在数据库中预生成电子邮件ID,然后通过调度程序传递id(int,UUID)
您生成模板上下文(JSON dict),然后将其传递给调度程序并在工作程序中呈现模板
您在调度程序中执行所有数据库提取和相关操作,并且不传递任何参数
具体来说,如何在调度程序中生成虚假request
对象的问题可以这样解决:
from pyramid import scripting
from pyramid.paster import bootstrap
def make_standalone_request():
bootstrap_env = bootstrap("your-pyramid-config.ini")
app = bootstrap_env["app"]
pyramid_env = scripting.prepare(registry=bootstrap_env["registry"])
request = pyramid_env["request"]
# Note that request.url will be always dummy,
# so if your email refers to site URL, you need to
# resolve request.route_url() calls before calling the scheduler
# or read the URLs from settings
return request
Some more inspiration can be found here (disclaimer: I am the author).