【问题标题】:Using Celery with Django: How do you save an object inside of a task?在 Django 中使用 Celery:如何在任务中保存对象?
【发布时间】:2021-02-21 14:13:20
【问题描述】:

我有一个 Django 项目并设置了一个 Celery 工人。我有一个测试任务,我尝试在其中创建一个对象并将其保存到数据库:

def get_genome():
    return Genome(genome_name='test-genome2', genome_sequence='AAAAA', organism='phage')

@shared_task
def test():
    sleep(10)
    g = get_genome()
    g.save()

我使用 test.delay() 在视图中调用任务。 sleep 命令和 get_genome commeand 在 celery worker 中执行,但是调用 .save() 返回以下错误:

[2020-11-09 10:53:09,131: ERROR/ForkPoolWorker-8] Task genome.tasks.test[cdd748a9-f889-4dae-bec6-3f869f96daf9] raised unexpected: TypeError('connect() argument 3 must be str, not None')
Traceback (most recent call last):
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/celery/app/trace.py", line 409, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/celery/app/trace.py", line 701, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/daemon/MAS/genome/tasks.py", line 14, in test
    g.save()
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base
    updated = self._save_table(
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/models/base.py", line 895, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert
    return manager._insert(
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/models/query.py", line 1254, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1395, in execute_sql
    with self.connection.cursor() as cursor:
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/backends/base/base.py", line 259, in cursor
    return self._cursor()
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    self.ensure_connection()
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/backends/base/base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 234, in get_new_connection
    return Database.connect(**conn_params)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/MySQLdb/__init__.py", line 130, in Connect
    return Connection(*args, **kwargs)
  File "/home/daemon/miniconda/envs/mas/lib/python3.8/site-packages/MySQLdb/connections.py", line 185, in __init__
    super().__init__(*args, **kwargs2)
TypeError: connect() argument 3 must be str, not None

如何配置 celery 使其能够正确使用 Django ORM 并保存对象?

我使用的是 Django 3.1.2 版和 celery 5.0.2 版

【问题讨论】:

标签: python django celery


【解决方案1】:

@iklinac 的评论让我弄清楚了问题所在。我从环境变量中提取数据库的密码:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'host': 'mas-sql-server',
            'database': 'mas',
            'user': 'root',
            'password': os.getenv('MYSQL_ROOT_PASSWORD')
        }
    }
}

这个环境变量在我运行 Celery worker 的环境中不可用。

【讨论】:

    猜你喜欢
    • 2020-02-03
    • 2014-03-16
    • 2016-03-31
    • 2016-10-14
    • 2015-09-07
    • 1970-01-01
    • 2018-04-14
    • 2011-10-07
    • 2018-11-12
    相关资源
    最近更新 更多