Запрос истек разница во времени в Django ORM
У меня есть простая модель для описания задачи и периода между ее выполнением:
class Task(models.Model):
last_check_timestamp = models.DateTimeField(blank=True, null=True, db_index=True)
class TaskSchedule(models.Model):
task = models.OneToOneField(Task, blank=False, null=False, related_name='schedule')
interval_seconds = models.IntegerField(blank=False, null=False)
Я хочу иметь возможность запрашивать, используя ORM Джанго, какие задачи свежие, а какие устаревшие, то есть те, которые должны выполняться в соответствии с их расписанием.
В настоящее время я вычисляю это для конкретной записи без ORM через:
import datetime
task = Task.objects.get(id=123)
fresh = task.last_check_timestamp is not None and datetime.datetime.now() < (task.last_check_timestamp + datetime.timedelta(seconds=task.schedule.interval_seconds))
Как бы я сделал эквивалент с ORM Джанго, чтобы я мог запросить все свежие / устаревшие задачи сразу?
Например, это очевидно, не работает, но что-то вроде:
Tasks.objects.filter(Q(last_check_timestamp__isnull=True) || Q(last_check_timestamp + datetime.timedelta(seconds=schedule__interval_seconds)))
1 ответ:
Недавно мне пришлось сделать аналогичный запрос. Я надеялся сделать это с помощью
F()
объекты, но я не думаю, что это возможно, потому что timedelta полагается на столбец db (это было бы возможно, если быschedule_interval_seconds
был константой).В конце концов, я сделал запрос, используя ORM с
extra()
, и написал SQL для предложения where.sql = "DATE_ADD(last_check_timestamp, INTERVAL schedule.interval_seconds SECOND) < DATE(NOW())" Tasks.objects.filter(Q(last_check_timestamp__isnull=True) || Q(last_check_timestamp + datetime.timedelta(seconds=schedule__interval_seconds))) tasks = Task.object.select_related('schedule').extra(where=[sql,]
Здесь используется функция
DATE_ADD
(MySQL docs). Возможно, вам придется приспособиться к различным вкусам SQL.select_related
требуется так что Джанго делает соединение с таблицей расписания.Выше не выбираются задачи, где
last_check_timestamp
равно null. Я не думаю, что вы можете использовать combineextra()
и ваш объектQ
, но вы можете расширить инструкцию SQL.sql = """last_check_timestamp is NULL or DATE_ADD(last_check_timestamp, INTERVAL schedule.interval_seconds SECOND) < DATE(NOW())"""