Description
Problem
The start()
method in the PostgresTimePartitionSize
class is currently non-deterministic when the unit is DAYS and value > 1. It simply returns the normalized date, without applying a fixed rule for grouping days into consistent, aligned partitions.
As a result, the same datetime value can be mapped to different partitions across different executions, depending on the runtime context. This leads to overlapping time intervals, which causes errors when creating physical partitions in PostgreSQL.
Real-world example
During the daily execution of the pgpartition
maintenance job (triggered via cron), the following error occurred:
InvalidObjectDefinition
partition "mymodel_2025_jun_04" would overlap partition "mymodel_2025_jun_03"
LINE 2: ...mymodel" FOR VALUES FROM ('2025-06-03' TO '2025-06-08')
This error indicates that the system attempted to create a partition (2025_jun_04
) with a time range that overlaps an existing partition (2025_jun_03
), violating PostgreSQL's partitioning constraints.
Proposed Solution
Update the start()
logic for DAYS to produce deterministic, consistent partition boundaries by anchoring the calculation to a fixed reference date (anchor_date
) and aligning windows using integer division:
anchor_date = datetime(1970, 1, 1, tzinfo=timezone.utc)
diff_days = (dt - anchor_date).days
partition_index = diff_days // value
start = anchor_date + timedelta(days=partition_index * value)
This ensures that:
- The same date always maps to the same partition
- Partition boundaries are stable, fixed, and predictable