@@ -254,6 +254,56 @@ def test_partitioning_time_daily_apply():
254254 assert table .partitions [6 ].name == "2019_jun_04"
255255
256256
257+ @pytest .mark .postgres_version (lt = 110000 )
258+ def test_partitioning_time_hourly_apply ():
259+ """Tests whether automatically creating new partitions ahead hourly works
260+ as expected."""
261+
262+ model = define_fake_partitioned_model (
263+ {"timestamp" : models .DateTimeField ()}, {"key" : ["timestamp" ]}
264+ )
265+
266+ schema_editor = connection .schema_editor ()
267+ schema_editor .create_partitioned_model (model )
268+
269+ # create partitions for the next 4 hours (including the current)
270+ with freezegun .freeze_time ("2019-1-23" ):
271+ manager = PostgresPartitioningManager (
272+ [partition_by_current_time (model , hours = 1 , count = 4 )]
273+ )
274+ manager .plan ().apply ()
275+
276+ table = _get_partitioned_table (model )
277+ assert len (table .partitions ) == 4
278+ assert table .partitions [0 ].name == "2019_jan_23_00:00:00"
279+ assert table .partitions [1 ].name == "2019_jan_23_01:00:00"
280+ assert table .partitions [2 ].name == "2019_jan_23_02:00:00"
281+ assert table .partitions [3 ].name == "2019_jan_23_03:00:00"
282+
283+ # re-running it with 5, should just create one additional partition
284+ with freezegun .freeze_time ("2019-1-23" ):
285+ manager = PostgresPartitioningManager (
286+ [partition_by_current_time (model , hours = 1 , count = 5 )]
287+ )
288+ manager .plan ().apply ()
289+
290+ table = _get_partitioned_table (model )
291+ assert len (table .partitions ) == 5
292+ assert table .partitions [4 ].name == "2019_jan_23_04:00:00"
293+
294+ # it's june now, we want to partition two hours ahead
295+ with freezegun .freeze_time ("2019-06-03" ):
296+ manager = PostgresPartitioningManager (
297+ [partition_by_current_time (model , hours = 1 , count = 2 )]
298+ )
299+ manager .plan ().apply ()
300+
301+ table = _get_partitioned_table (model )
302+ assert len (table .partitions ) == 7
303+ assert table .partitions [5 ].name == "2019_jun_03_00:00:00"
304+ assert table .partitions [6 ].name == "2019_jun_03_01:00:00"
305+
306+
257307@pytest .mark .postgres_version (lt = 110000 )
258308def test_partitioning_time_consistent_daily_apply ():
259309 """Ensures that automatic daily partition creation is consistent and
@@ -415,11 +465,52 @@ def test_partitioning_time_daily_apply_insert():
415465 model .objects .create (timestamp = datetime .date (2019 , 1 , 10 ))
416466
417467
468+ @pytest .mark .postgres_version (lt = 110000 )
469+ def test_partitioning_time_hourly_apply_insert ():
470+ """Tests whether automatically created hourly partitions line up
471+ perfectly."""
472+
473+ model = define_fake_partitioned_model (
474+ {"timestamp" : models .DateTimeField ()}, {"key" : ["timestamp" ]}
475+ )
476+
477+ schema_editor = connection .schema_editor ()
478+ schema_editor .create_partitioned_model (model )
479+
480+ # that's a monday
481+ with freezegun .freeze_time ("2019-1-07" ):
482+ manager = PostgresPartitioningManager (
483+ [partition_by_current_time (model , hours = 1 , count = 2 )]
484+ )
485+ manager .plan ().apply ()
486+
487+ table = _get_partitioned_table (model )
488+ assert len (table .partitions ) == 2
489+
490+ model .objects .create (timestamp = datetime .datetime (2019 , 1 , 7 , 0 ))
491+ model .objects .create (timestamp = datetime .datetime (2019 , 1 , 7 , 1 ))
492+
493+ with transaction .atomic ():
494+ with pytest .raises (IntegrityError ):
495+ model .objects .create (timestamp = datetime .datetime (2019 , 1 , 7 , 2 ))
496+ model .objects .create (timestamp = datetime .datetime (2019 , 1 , 7 , 3 ))
497+
498+ with freezegun .freeze_time ("2019-1-07" ):
499+ manager = PostgresPartitioningManager (
500+ [partition_by_current_time (model , hours = 1 , count = 4 )]
501+ )
502+ manager .plan ().apply ()
503+
504+ model .objects .create (timestamp = datetime .datetime (2019 , 1 , 7 , 2 ))
505+ model .objects .create (timestamp = datetime .datetime (2019 , 1 , 7 , 3 ))
506+
507+
418508@pytest .mark .postgres_version (lt = 110000 )
419509@pytest .mark .parametrize (
420510 "kwargs,partition_names" ,
421511 [
422512 (dict (days = 2 ), ["2018_dec_31" , "2019_jan_02" ]),
513+ (dict (hours = 2 ), ["2019_jan_01_00:00:00" , "2019_jan_01_02:00:00" ]),
423514 (dict (weeks = 2 ), ["2018_week_53" , "2019_week_02" ]),
424515 (dict (months = 2 ), ["2019_jan" , "2019_mar" ]),
425516 (dict (years = 2 ), ["2019" , "2021" ]),
0 commit comments