返回介绍

任务的数据库表示

发布于 2025-01-02 21:54:01 字数 2287 浏览 0 评论 0 收藏 0

对于上面的例子来说,启动一个任务并观察它运行就足够了。 对于 Web 应用程序,情况会变得更复杂一些,因为一旦任务随着请求的处理而启动,该请求随即结束,而该任务的所有上下文都将丢失。 因为我希望应用程序跟踪每个用户正在运行的任务,所以我需要使用数据库表来维护状态。 你可以在下面看到新的 Task 模型实现:

app/models.py :Task 模型。

# ...
import redis
import rq

class User(UserMixin, db.Model):
    # ...
    tasks = db.relationship('Task', backref='user', lazy='dynamic')

# ...

class Task(db.Model):
    id = db.Column(db.String(36), primary_key=True)
    name = db.Column(db.String(128), index=True)
    description = db.Column(db.String(128))
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    complete = db.Column(db.Boolean, default=False)

    def get_rq_job(self):
        try:
            rq_job = rq.job.Job.fetch(self.id, connection=current_app.redis)
        except (redis.exceptions.RedisError, rq.exceptions.NoSuchJobError):
            return None
        return rq_job

    def get_progress(self):
        job = self.get_rq_job()
        return job.meta.get('progress', 0) if job is not None else 100

这个模型和以前的模型有一个有趣的区别是 id 主键字段是字符串类型,而不是整数类型。 这是因为对于这个模型,我不会依赖数据库自己的主键生成,而是使用由 RQ 生成的作业标识符。

该模型将存储符合任务命名规范的名称(会传递给 RQ),适用于向用户显示的任务描述,该任务的所属用户的关系以及任务是否已完成的布尔值。 complete 字段的目的是将正在运行的任务与已完成的任务分开,因为运行中的任务需要特殊处理才能显示最新进度。

get_rq_job() 辅助方法可以用给定的任务 ID 加载 RQ Job 实例。 这是通过 Job.fetch() 完成的,它会从 Redis 中存在的数据中加载 Job 实例。 get_progress() 方法建立在 get_rq_job() 的基础之上,并返回任务的进度百分比。 该方法做一些有趣的假设,如果模型中的作业 ID 不存在于 RQ 队列中,则表示作业已完成并且数据已过期并已从队列中删除,因此在这种情况下返回的百分比为 100。 另一方面,如果 job 存在,但'meta'属性中找不到进度相关的信息,那么可以安全地假定该 job 计划运行,但还没有启动,所以在这种情况下进度是 0。

要将更改应用于数据库,需要生成新的迁移,然后升级数据库:

(venv) $ flask db migrate -m "tasks"
(venv) $ flask db upgrade

新模型也可以添加到 shell 上下文中,以便在 shell 会话中访问它时无需导入:

microblog.py :添加 Task 模型到 shell 上下文中。

from app import create_app, db, cli
from app.models import User, Post, Message, Notification, Task

app = create_app()
cli.register(app)

@app.shell_context_processor
def make_shell_context():
    return {'db': db, 'User': User, 'Post': Post, 'Message': Message,
            'Notification': Notification, 'Task': Task}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文