Python + Celery + SQLAlchemy(sqlite)->不能按预期工作

时间:2018-08-11 11:00:59

标签: python sqlite sqlalchemy celery

我目前可能无法通过SQLAlchemy(sqlite内存数据库)运行celery或celery-worker。

这是我的简单设置:

proj / db.py:(具有sqlalchemy和scoped_sessions的简单数据库)

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base


engine = create_engine('sqlite:///:memory:', convert_unicode=True, pool_recycle=3600, pool_size=10, echo=False)
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    password = Column(String)

    def __repr__(self):
        return "<User(name='%s', fullname='%s', password='%s')>" %     (self.name, self.fullname, self.password)

Base.metadata.create_all(engine)

proj / celery.py (芹菜配置,包括proj.tasks)

from __future__ import absolute_import
from celery import Celery
import config

celery = Celery('app', broker='redis://{}:{}/{}'.format(config.R_HOST,    config.R_PORT, config.R_DB),
            backend='redis://{}:{}/{}'.format(config.R_HOST, config.R_PORT, config.R_DB),
            include=["proj.tasks"])

if __name__ == '__main__':
    celery.start()

proj / tasks.py (用于读写数据库的简单任务)

from __future__ import absolute_import
from proj.celery import celery
from proj.db import db_session, User
from celery import Task

class SqlAlchemyTask(Task):
    abstract = True

    def after_return(self, status, retval, task_id, args, kwargs, einfo):
        db_session.remove()


@celery.task(base=SqlAlchemyTask)
def setdb():
    u = User(id=10, name="NAME", fullname="FULL", password="PASS")
    db_session.add(u)
    db_session.commit()
    print("INSERT")

@celery.task(base=SqlAlchemyTask)
def get_from_db():
    print(db_session.query(User).all())

config.py (配置文件)

R_HOST = "127.0.0.1"
R_PORT = 6379
R_DB = 0

run.py (执行的文件)

from proj.db import db_session
from proj.db import User
from proj.tasks import get_from_db, setdb
import time

setdb.apply_async()
time.sleep(10)
get_from_db.apply_async()
get_from_db.apply_async()
get_from_db.apply_async()
get_from_db.apply_async()
time.sleep(10)
print(db_session.query(User).all())

如果我现在启动redis服务器,celery,然后运行run.py,则会发生一些奇怪的事情。我的程序通过setdb.apply_async()调用在数据库中插入一个条目。 10秒钟后,程序将使用get_from_db.apply_async()查询数据。所有这些都是由芹菜完成的。我希望所有工作人员都可以访问插入的数据,但是芹菜日志显示了其他内容。

芹菜日志

celery -A proj worker

[2018-08-11 11:32:34,959: WARNING/SpawnPoolWorker-2] INSERT
[2018-08-11 11:32:40,767: WARNING/SpawnPoolWorker-1] []
[2018-08-11 11:32:40,769: WARNING/SpawnPoolWorker-3] []
[2018-08-11 11:32:40,771: WARNING/SpawnPoolWorker-4] []
[2018-08-11 11:32:40,773: WARNING/SpawnPoolWorker-2] [<User(name='NAME', fullname='FULL', password='PASS')>]

主程序也看不到任何数据(print(db_session.query(User).all())): python run.py

[]

尽管celery-worker 2插入了一个条目,但是其他工人或主程序(run.py)在数据库中看不到任何数据。 我该如何解决此问题,以便我可以在每个工作人员和主程序中访问相同的数据。不管是哪个工人进入的?

问候杰夫

0 个答案:

没有答案