问题描述
我在基于 Docker 的设置上安装了 Django Celery 和 Beat。我的设置分为他们相关的环境。 base.py
包含 staging.py
和 production.py
所需的通用配置。在我的 common.py
中,我正在初始化一个类似这样的变量
from datetime import datetime
import pytz
est_timezone = datetime.Now(pytz.timezone('EST'))
这是我得到的回溯
celery-beat_1 | [2021-04-09 10:59:46,845: CRITICAL/MainProcess] beat raised exception <class 'TypeError'>: TypeError("'datetime.datetime' object is not callable")
你可以把上面的代码片段放在一个 shell 中,它运行良好,所以我不知道发生了什么。
这是使用 est_timezone 变量的地方
CELERY_BEAT_SCHEDULE = {
'fetch_rates_on_weekdays': {
'task': 'where the task at','schedule': crontab(hour=CELERY_TIME_FOR_FETCH_RATES_ON_WEEKENDS,day_of_week='1-5',Nowfun=est_timezone)
}
}
追溯
celery-beat_1 | [2021-04-12 07:44:58,058: CRITICAL/MainProcess] beat raised exception <class 'AttributeError'>: AttributeError("module 'datetime' has no attribute 'Now'")
celery-beat_1 | Traceback (most recent call last):
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/kombu/utils/objects.py",line 41,in __get__
celery-beat_1 | return obj.__dict__[self.__name__]
celery-beat_1 | KeyError: 'scheduler'
celery-beat_1 |
celery-beat_1 | During handling of the above exception,another exception occurred:
celery-beat_1 |
celery-beat_1 | Traceback (most recent call last):
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/apps/beat.py",line 105,in start_scheduler
celery-beat_1 | service.start()
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 618,in start
celery-beat_1 | humanize_seconds(self.scheduler.max_interval))
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/kombu/utils/objects.py",line 43,in __get__
celery-beat_1 | value = obj.__dict__[self.__name__] = self.__get(obj)
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 662,in scheduler
celery-beat_1 | return self.get_scheduler()
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 657,in get_scheduler
celery-beat_1 | lazy=lazy,celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 497,in __init__
celery-beat_1 | Scheduler.__init__(self,*args,**kwargs)
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 253,in __init__
celery-beat_1 | self.setup_schedule()
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 540,in setup_schedule
celery-beat_1 | self.merge_inplace(self.app.conf.beat_schedule)
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 450,in merge_inplace
celery-beat_1 | entry = self.Entry(**dict(b[key],name=key,app=self.app))
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 124,in __init__
celery-beat_1 | self.last_run_at = last_run_at or self.default_Now()
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/beat.py",line 128,in default_Now
celery-beat_1 | return self.schedule.Now() if self.schedule else self.app.Now()
celery-beat_1 | File "/usr/local/lib/python3.7/site-packages/celery/schedules.py",line 67,in Now
celery-beat_1 | return (self.Nowfun or self.app.Now)()
celery-beat_1 | File "/app/app/settings/common.py",line 146,in est_timezone
celery-beat_1 | return datetime.Now(pytz.timezon('EST'))
celery-beat_1 | AttributeError: module 'datetime' has no attribute 'Now'
celery-beat_1 | [2021-04-12 07:44:58,059: WARNING/MainProcess] Traceback (most recent call last):
celery-beat_1 | [2021-04-12 07:44:58,059: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/kombu/utils/objects.py",in __get__
celery-beat_1 | [2021-04-12 07:44:58,059: WARNING/MainProcess] return obj.__dict__[self.__name__]
celery-beat_1 | [2021-04-12 07:44:58,059: WARNING/MainProcess] KeyError
celery-beat_1 | [2021-04-12 07:44:58,059: WARNING/MainProcess] :
celery-beat_1 | [2021-04-12 07:44:58,059: WARNING/MainProcess] 'scheduler'
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] During handling of the above exception,another exception occurred:
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] Traceback (most recent call last):
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] File "/usr/local/bin/celery",line 8,in <module>
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] sys.exit(main())
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/__main__.py",line 15,in main
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] sys.exit(_main())
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/bin/celery.py",line 213,060: WARNING/MainProcess] return celery(auto_envvar_prefix="CELERY")
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/click/core.py",line 829,in __call__
celery-beat_1 | [2021-04-12 07:44:58,060: WARNING/MainProcess] return self.main(*args,**kwargs)
celery-beat_1 | [2021-04-12 07:44:58,line 782,061: WARNING/MainProcess] rv = self.invoke(ctx)
celery-beat_1 | [2021-04-12 07:44:58,061: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/click/core.py",line 1259,in invoke
celery-beat_1 | [2021-04-12 07:44:58,061: WARNING/MainProcess] return _process_result(sub_ctx.command.invoke(sub_ctx))
celery-beat_1 | [2021-04-12 07:44:58,line 1066,061: WARNING/MainProcess] return ctx.invoke(self.callback,**ctx.params)
celery-beat_1 | [2021-04-12 07:44:58,line 610,062: WARNING/MainProcess] return callback(*args,062: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/click/decorators.py",line 21,in new_func
celery-beat_1 | [2021-04-12 07:44:58,062: WARNING/MainProcess] return f(get_current_context(),062: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/bin/base.py",line 132,in caller
celery-beat_1 | [2021-04-12 07:44:58,062: WARNING/MainProcess] return f(ctx,062: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/bin/beat.py",line 72,in beat
celery-beat_1 | [2021-04-12 07:44:58,062: WARNING/MainProcess] return beat().run()
celery-beat_1 | [2021-04-12 07:44:58,062: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/apps/beat.py",line 77,in run
celery-beat_1 | [2021-04-12 07:44:58,062: WARNING/MainProcess] self.start_scheduler()
celery-beat_1 | [2021-04-12 07:44:58,in start_scheduler
celery-beat_1 | [2021-04-12 07:44:58,062: WARNING/MainProcess] service.start()
celery-beat_1 | [2021-04-12 07:44:58,062: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/beat.py",in start
celery-beat_1 | [2021-04-12 07:44:58,063: WARNING/MainProcess] humanize_seconds(self.scheduler.max_interval))
celery-beat_1 | [2021-04-12 07:44:58,063: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/kombu/utils/objects.py",063: WARNING/MainProcess] value = obj.__dict__[self.__name__] = self.__get(obj)
celery-beat_1 | [2021-04-12 07:44:58,063: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/beat.py",in scheduler
celery-beat_1 | [2021-04-12 07:44:58,063: WARNING/MainProcess] return self.get_scheduler()
celery-beat_1 | [2021-04-12 07:44:58,in get_scheduler
celery-beat_1 | [2021-04-12 07:44:58,063: WARNING/MainProcess] lazy=lazy,celery-beat_1 | [2021-04-12 07:44:58,in __init__
celery-beat_1 | [2021-04-12 07:44:58,063: WARNING/MainProcess] Scheduler.__init__(self,064: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/beat.py",064: WARNING/MainProcess] self.setup_schedule()
celery-beat_1 | [2021-04-12 07:44:58,in setup_schedule
celery-beat_1 | [2021-04-12 07:44:58,064: WARNING/MainProcess] self.merge_inplace(self.app.conf.beat_schedule)
celery-beat_1 | [2021-04-12 07:44:58,in merge_inplace
celery-beat_1 | [2021-04-12 07:44:58,064: WARNING/MainProcess] entry = self.Entry(**dict(b[key],app=self.app))
celery-beat_1 | [2021-04-12 07:44:58,064: WARNING/MainProcess] self.last_run_at = last_run_at or self.default_Now()
celery-beat_1 | [2021-04-12 07:44:58,in default_Now
celery-beat_1 | [2021-04-12 07:44:58,064: WARNING/MainProcess] return self.schedule.Now() if self.schedule else self.app.Now()
celery-beat_1 | [2021-04-12 07:44:58,065: WARNING/MainProcess] File "/usr/local/lib/python3.7/site-packages/celery/schedules.py",in Now
celery-beat_1 | [2021-04-12 07:44:58,065: WARNING/MainProcess] return (self.Nowfun or self.app.Now)()
celery-beat_1 | [2021-04-12 07:44:58,065: WARNING/MainProcess] File "/app/app/settings/common.py",in est_timezone
celery-beat_1 | [2021-04-12 07:44:58,065: WARNING/MainProcess] return datetime.Now(pytz.timezon('EST'))
celery-beat_1 | [2021-04-12 07:44:58,065: WARNING/MainProcess] AttributeError
celery-beat_1 | [2021-04-12 07:44:58,065: WARNING/MainProcess] :
celery-beat_1 | [2021-04-12 07:44:58,065: WARNING/MainProcess] module 'datetime' has no attribute 'Now'
解决方法
如果您查看 Celery 的文档,nowfun 需要一个可调用函数,而您正在传递一个日期时间对象。 Celery Doc
nowfun (Callable) – 返回当前日期和时间的函数 类:~datetime.datetime。
所以在这种情况下,您可以简单地将您的 est_timezone 更改为一个函数:
def est_timezone():
return datetime.now(pytz.timezone('EST'))
您的日程安排 crontab 将保持不变。