Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,36 @@ paths:
schema:
type: string
title: Dag Id
- name: partition_date_gte
in: query
required: false
schema:
anyOf:
- type: string
format: date
- type: 'null'
description: Inclusive lower bound of the partition_date window, interpreted
as a local calendar day in the Dag's timetable timezone. Runs from the
start of this day onwards match.
title: Partition Date Gte
description: Inclusive lower bound of the partition_date window, interpreted
as a local calendar day in the Dag's timetable timezone. Runs from the start
of this day onwards match.
- name: partition_date_lte
in: query
required: false
schema:
anyOf:
- type: string
format: date
- type: 'null'
description: 'Inclusive upper bound of the partition_date window, interpreted
as a local calendar day in the Dag''s timetable timezone. The whole day
is included: runs up to the end of this day match.'
title: Partition Date Lte
description: 'Inclusive upper bound of the partition_date window, interpreted
as a local calendar day in the Dag''s timetable timezone. The whole day
is included: runs up to the end of this day match.'
- name: cursor
in: query
required: false
Expand Down Expand Up @@ -2614,15 +2644,15 @@ paths:
type: string
description: 'Attributes to order by, multi criteria sort is supported.
Prefix with `-` for descending order. Supported attributes: `id, state,
dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at,
conf, duration, dag_run_id`'
dag_id, run_id, logical_date, partition_date, run_after, start_date, end_date,
updated_at, conf, duration, dag_run_id`'
default:
- id
title: Order By
description: 'Attributes to order by, multi criteria sort is supported. Prefix
with `-` for descending order. Supported attributes: `id, state, dag_id,
run_id, logical_date, run_after, start_date, end_date, updated_at, conf,
duration, dag_run_id`'
run_id, logical_date, partition_date, run_after, start_date, end_date, updated_at,
conf, duration, dag_run_id`'
- name: run_id_pattern
in: query
required: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from __future__ import annotations

import datetime
import textwrap
from typing import Annotated, Literal, cast

Expand Down Expand Up @@ -509,6 +510,7 @@ def get_dag_runs(
"dag_id",
"run_id",
"logical_date",
"partition_date",
"run_after",
"start_date",
"end_date",
Expand Down Expand Up @@ -547,6 +549,21 @@ def get_dag_runs(
partition_key_pattern: QueryDagRunPartitionKeySearch,
partition_key_prefix_pattern: QueryDagRunPartitionKeyPrefixSearch,
consuming_asset_pattern: QueryConsumingAssetPatternSearch,
partition_date_gte: datetime.date | None = Query(
None,
description=(
"Inclusive lower bound of the partition_date window, interpreted as a local calendar "
"day in the Dag's timetable timezone. Runs from the start of this day onwards match."
),
),
partition_date_lte: datetime.date | None = Query(
None,
description=(
"Inclusive upper bound of the partition_date window, interpreted as a local calendar "
"day in the Dag's timetable timezone. The whole day is included: runs up to the end "
"of this day match."
),
),
cursor: str | None = Query(
None,
description="Cursor for keyset-based pagination. "
Expand All @@ -571,9 +588,46 @@ def get_dag_runs(
use_cursor = cursor is not None
query = select(DagRun).options(*eager_load_dag_run_for_list())

if dag_id != "~":
get_latest_version_of_dag(dag_bag, dag_id, session) # Check if the Dag exists.
has_partition_date_filter = partition_date_gte is not None or partition_date_lte is not None

if dag_id == "~":
if has_partition_date_filter:
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
"partition_date_gte and partition_date_lte require a specific dag_id.",
)
else:
dag = get_latest_version_of_dag(dag_bag, dag_id, session) # Check if the Dag exists.
query = query.filter(DagRun.dag_id == dag_id).options()
if has_partition_date_filter:
# Runs of a non-partitioned Dag never carry a partition_date (this includes
# partitioned-at-runtime Dags, whose runs keep it NULL), so the filter would
# silently match nothing; reject it instead.
if not dag.timetable.partitioned:
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
f"Dag with dag_id: '{dag_id}' is not partitioned; "
"partition_date_gte and partition_date_lte are not supported.",
)
# The bounds are calendar days, so the whole of partition_date_lte belongs to the
# window: widen it to the following local midnight and exclude that edge.
query = DagRun.apply_partition_date_window(
query,
timetable=dag.timetable,
start=(
datetime.datetime.combine(partition_date_gte, datetime.time.min)
if partition_date_gte is not None
else None
),
end=(
datetime.datetime.combine(
partition_date_lte + datetime.timedelta(days=1), datetime.time.min
)
if partition_date_lte is not None
else None
),
end_exclusive=True,
)

# Add join with DagVersion if dag_version filter is active
if dag_version.value:
Expand Down
14 changes: 12 additions & 2 deletions airflow-core/src/airflow/models/dagrun.py
Original file line number Diff line number Diff line change
Expand Up @@ -2225,14 +2225,24 @@ def apply_partition_date_window(
timetable: Timetable,
start: datetime | None,
end: datetime | None,
end_exclusive: bool = False,
) -> Select:
"""Filter stmt to the inclusive interval [lower, upper] on partition_date."""
"""
Filter stmt to a partition_date window bounded by *start* and *end*.

The lower bound is always inclusive. The upper bound is inclusive by default;
pass ``end_exclusive=True`` when *end* is the open edge of the window, as with
a date-only filter widened to the following local midnight.
"""
if start is not None:
lower = timetable.localize_partition_datetime(start)
stmt = stmt.where(DagRun.partition_date >= lower)
if end is not None:
upper = timetable.localize_partition_datetime(end)
stmt = stmt.where(DagRun.partition_date <= upper)
if end_exclusive:
stmt = stmt.where(DagRun.partition_date < upper)
else:
stmt = stmt.where(DagRun.partition_date <= upper)
return stmt


Expand Down
6 changes: 4 additions & 2 deletions airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export const UseDagRunServiceGetDagRunKeyFn = ({ dagId, dagRunId }: {
export type DagRunServiceGetDagRunsDefaultResponse = Awaited<ReturnType<typeof DagRunService.getDagRuns>>;
export type DagRunServiceGetDagRunsQueryResult<TData = DagRunServiceGetDagRunsDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>;
export const useDagRunServiceGetDagRunsKey = "DagRunServiceGetDagRuns";
export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: {
export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: {
bundleVersion?: string;
confContains?: string;
consumingAssetPattern?: string;
Expand All @@ -180,6 +180,8 @@ export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, c
logicalDateLte?: string;
offset?: number;
orderBy?: string[];
partitionDateGte?: string;
partitionDateLte?: string;
partitionKeyPattern?: string;
partitionKeyPrefixPattern?: string;
runAfterGt?: string;
Expand All @@ -200,7 +202,7 @@ export const UseDagRunServiceGetDagRunsKeyFn = ({ bundleVersion, confContains, c
updatedAtGte?: string;
updatedAtLt?: string;
updatedAtLte?: string;
}, queryKey?: Array<unknown>) => [useDagRunServiceGetDagRunsKey, ...(queryKey ?? [{ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }])];
}, queryKey?: Array<unknown>) => [useDagRunServiceGetDagRunsKey, ...(queryKey ?? [{ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }])];
export type DagRunServiceGetUpstreamAssetEventsDefaultResponse = Awaited<ReturnType<typeof DagRunService.getUpstreamAssetEvents>>;
export type DagRunServiceGetUpstreamAssetEventsQueryResult<TData = DagRunServiceGetUpstreamAssetEventsDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>;
export const useDagRunServiceGetUpstreamAssetEventsKey = "DagRunServiceGetUpstreamAssetEvents";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ export const ensureUseDagRunServiceGetDagRunData = (queryClient: QueryClient, {
* on the first page.
* @param data The data for the request.
* @param data.dagId
* @param data.partitionDateGte Inclusive lower bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. Runs from the start of this day onwards match.
* @param data.partitionDateLte Inclusive upper bound of the partition_date window, interpreted as a local calendar day in the Dag's timetable timezone. The whole day is included: runs up to the end of this day match.
* @param data.cursor Cursor for keyset-based pagination. Pass an empty string for the first page, then use ``next_cursor`` from the response. When ``cursor`` is provided, ``offset`` is ignored.
* @param data.limit
* @param data.offset
Expand Down Expand Up @@ -339,7 +341,7 @@ export const ensureUseDagRunServiceGetDagRunData = (queryClient: QueryClient, {
* @param data.state
* @param data.dagVersion
* @param data.bundleVersion
* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id`
* @param data.orderBy Attributes to order by, multi criteria sort is supported. Prefix with `-` for descending order. Supported attributes: `id, state, dag_id, run_id, logical_date, partition_date, run_after, start_date, end_date, updated_at, conf, duration, dag_run_id`
* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Use the pipe `|` operator for OR logic (e.g. `dag1 | dag2`). Regular expressions are **not** supported.
*
* **Performance note:** this full-match pattern is evaluated as ``ILIKE '%term%'`` and most of the time prevents the database from using B-tree indexes, which can be very slow on large tables. Prefer the equivalent ``run_id_prefix_pattern`` parameter when possible.
Expand All @@ -360,7 +362,7 @@ export const ensureUseDagRunServiceGetDagRunData = (queryClient: QueryClient, {
* @returns DAGRunCollectionResponse Successful Response
* @throws ApiError
*/
export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: {
export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, { bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }: {
bundleVersion?: string;
confContains?: string;
consumingAssetPattern?: string;
Expand All @@ -384,6 +386,8 @@ export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, {
logicalDateLte?: string;
offset?: number;
orderBy?: string[];
partitionDateGte?: string;
partitionDateLte?: string;
partitionKeyPattern?: string;
partitionKeyPrefixPattern?: string;
runAfterGt?: string;
Expand All @@ -404,7 +408,7 @@ export const ensureUseDagRunServiceGetDagRunsData = (queryClient: QueryClient, {
updatedAtGte?: string;
updatedAtLt?: string;
updatedAtLte?: string;
}) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) });
}) => queryClient.ensureQueryData({ queryKey: Common.UseDagRunServiceGetDagRunsKeyFn({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }), queryFn: () => DagRunService.getDagRuns({ bundleVersion, confContains, consumingAssetPattern, cursor, dagId, dagIdPattern, dagIdPrefixPattern, dagVersion, durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte, offset, orderBy, partitionDateGte, partitionDateLte, partitionKeyPattern, partitionKeyPrefixPattern, runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, runIdPrefixPattern, runType, startDateGt, startDateGte, startDateLt, startDateLte, state, triggeringUserNamePattern, triggeringUserNamePrefixPattern, updatedAtGt, updatedAtGte, updatedAtLt, updatedAtLte }) });
/**
* Get Upstream Asset Events
* If dag run is asset-triggered, return the asset events that triggered it.
Expand Down
Loading
Loading