从MySQL查询返回的每一行运行Celery任务?

时间:2016-08-01 22:10:03

标签: python mysql celery

之前我曾使用过Python,但仅限于Flask应用程序,但我之前从未使用过Celery。在阅读完文档并设置所有内容之后(并且它在我与多个工作人员一起测试过的情况下工作)我尝试运行SQL查询,并且对于从查询返回的每一行,将其发送为由芹菜工人处理。

以下是最基本代码的示例。

from celery import Celery
import MySQLdb

app = Celery('tasks', broker='redis://localhost:6379/0')
@app.task
def print_domain():
    db = MySQLdb.connect(host="localhost", user="DB_USER", passwd="DB_PASS", db="DB_NAME")
    cur = db.cursor()
    cur.execute("SELECT * FROM myTable")

    for row in cur.fetchall():
        print_query_result(row[0])

    db.close()

def print_query_result(result):
    print result

基本上它会选择“myTable”中的所有内容。表和返回的每一行都打印出来。如果我只使用Python调用代码,它可以正常工作并打印MySQL表中的所有数据。当我使用.delay()函数将其发送给工作人员进行处理时,只将其发送给一个工作人员,并仅输出数据库中的顶行。

我一直试图读取子任务,但我不确定我是否会朝着正确的方向前进。

简而言之,我希望这种情况发生,但我无从何处开始。有没有人有任何想法?

  • SQL查询以选择表中的所有行
  • 将每行/结果发送给工作人员以处理一些代码
  • 将代码结果返回数据库
  • 选择队列中的下一个项目(如果有)

提前致谢。

编辑1:

我已经更新了我的代码以使用SQLAlchemy,但结果仍然像我的旧查询一样返回,这很好。

from celery import Celery
from models import DBDomains

app = Celery('tasks', broker='redis://localhost:6379/0')
@app.task
def print_domain():
    query = DBDomains.query.all()
    for i in query:
        print i.domain
        print_query_result.s()

@app.task
def print_query_result():
    print "Received job"

print_domain.delay()

运行.py文件时,worker返回:

[2016-08-02 02:08:40,881: INFO/MainProcess] Received task: tasks.print_domain[65d7667a-fc70-41f7-8caa-b991f360a9de]
[2016-08-02 02:08:41,036: WARNING/Worker-3] result1
[2016-08-02 02:08:41,037: WARNING/Worker-3] result2
[2016-08-02 02:08:41,039: INFO/MainProcess] Task tasks.print_domain[65d7667a-fc70-41f7-8caa-b991f360a9de] succeeded in 0.154022816569s: None

正如您所看到的,工作人员获得了结果1'和'结果2'从表中我查询但是它似乎没有在子任务中执行命令,只是打印"作业已收到"。

更新:根据Celery文档,看起来子任务必须在它的末尾有一个.delay()所以我的代码看起来像这样,并且现在成功地在工作人员之间分配作业。

from celery import Celery
from models import DBDomains

app = Celery('tasks', broker='redis://localhost:6379/0')
@app.task
def print_domain():
    query = DBDomains.query.all()
    for i in query:
        subtask = print_query_result.s(i.domain)
        subtask.delay()


@app.task
def print_query_result(domain):
    print domain

 print_domain.delay()

1 个答案:

答案 0 :(得分:2)

每当您从任务中调用任务时,都必须使用subtasks。幸运的是语法很简单。

from celery import Celery

app = Celery('tasks', broker='redis://127.0.0.1:6379/0')


@app.task
def print_domain():
    for x in range(20):
        print_query_result.s(x)


@app.task
def print_query_result(result):
    print(result)

(用您的查询结果替换范围(20)中的x。)如果您正在观察芹菜输出,您将看到在工作人员中创建和分发的任务。