通过Python / Django在数据库中表示计划的最佳方法是什么?

时间:2009-03-06 16:56:51

标签: python django django-models backup django-forms

我正在使用Django前端编写Python备份系统。我决定以一种稍微奇怪的方式实现调度 - 客户端将轮询服务器(每10分钟左右),以获取需要执行的备份列表。服务器仅在到达备份时间时才会响应。这是为了保持系统平台独立 - 这样我就不依赖于cronjobs等。因此,Django前端(公开XML-RPC API)必须将调度存储在数据库中,并解释该调度以确定客户端是否应该开始备份。

目前,时间表使用3个字段存储:日,小时和分钟。这些是以逗号分隔的整数列表,表示一周中的日期(0-6),一天中的小时(0-23)和小时的分钟(0-59)。要确定客户端是否应该开始备份是一种非常低效的操作 - Python必须在过去7天后的所有日子里循环,然后是小时,然后是分钟。我做了一些优化,以确保它不会循环太多 - 但仍然!

虽然实施起来非常难看,但效果相对较好。我遇到的问题是如何通过前端的HTML表单显示和解释这些信息。目前我只有大量的多选字段列表,显然效果不佳。

任何人都可以建议一种不同的方法来实现更高效的计划,并且更容易在HTML表单中表示吗?

2 个答案:

答案 0 :(得分:3)

看看django-chronograph。它有一个非常好的界面,可以在各种间隔调度作业。你也许可以从中借鉴一些想法。它依赖于python-dateutil,您可能会发现它对指定重复事件很有用。

答案 1 :(得分:0)

您的问题有点含糊不清 - 您的意思是:"每个星期日,星期一和星期五在X时间备份。"

如果是这样,请使用Bitmask将定期计划存储为整数:

让我们假设你想要一个如上所述的备份 - 星期日,星期一和星期五。将星期几编码为整数(以二进制表示):

S M T W T F S
1 1 0 0 0 1 0 = 98

要了解今天(例如星期五)是否为备用日,只需按位and执行:

>>> 0b1100010 & 0b0000010 != 0
True

要将当前日期作为整数,您需要将其偏移一,因为weekday()假定周一开始一周:

current_day = (timezone.now().weekday() + 1) % 7

总之,Schedule对象的架构如下所示:

class Schedule(models.Model):
    days_recurrence = models.PositiveSmallIntegerField(db_index=True)
    time = models.TimeField()

使用此架构,您需要为要备份的每一天的新Schedule对象。这是一个快速查找,因为按位运算需要花费大约2个周期,并且由于您要对字段days_recurrence建立索引,因此您对O(logn)进行了最差情况的日期查找,这会降低您的复杂性相当。如果你想从中获得更多性能,你也可以使用位掩码小时然后存储分钟。