繁体   English   中英

在 Django 中使用 Celery:如何在任务中保存对象?

[英]Using Celery with Django: How do you save an object inside of a task?

我有一个 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 命令在 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 版

@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 的环境中不可用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM