コード例 #1
0
def test_partitioning_time_daily_apply_insert():
    """Tests whether automatically created daily partitions line up
    perfectly."""

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    # that's a monday
    with freezegun.freeze_time("2019-1-07"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, days=1, count=2)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 2

    model.objects.create(timestamp=datetime.date(2019, 1, 7))
    model.objects.create(timestamp=datetime.date(2019, 1, 8))

    with transaction.atomic():
        with pytest.raises(IntegrityError):
            model.objects.create(timestamp=datetime.date(2019, 1, 9))
            model.objects.create(timestamp=datetime.date(2019, 1, 10))

    with freezegun.freeze_time("2019-1-07"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, days=1, count=4)])
        manager.plan().apply()

    model.objects.create(timestamp=datetime.date(2019, 1, 9))
    model.objects.create(timestamp=datetime.date(2019, 1, 10))
コード例 #2
0
def test_partitioning_time_monthly_apply_insert():
    """Tests whether automatically created monthly partitions line up
    perfectly."""

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    with freezegun.freeze_time("2019-1-1"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, months=1, count=2)])
        manager.plan().apply()

    model.objects.create(timestamp=datetime.date(2019, 1, 1))
    model.objects.create(timestamp=datetime.date(2019, 1, 31))
    model.objects.create(timestamp=datetime.date(2019, 2, 28))

    with transaction.atomic():
        with pytest.raises(IntegrityError):
            model.objects.create(timestamp=datetime.date(2019, 3, 1))
            model.objects.create(timestamp=datetime.date(2019, 3, 2))

    with freezegun.freeze_time("2019-1-1"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, months=1, count=3)])
        manager.plan().apply()

    model.objects.create(timestamp=datetime.date(2019, 3, 1))
    model.objects.create(timestamp=datetime.date(2019, 3, 2))
コード例 #3
0
def test_partitioning_time_yearly_apply():
    """Tests whether automatically creating new partitions ahead yearly works
    as expected."""

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    with freezegun.freeze_time("2019-1-1"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, years=1, count=2)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 2
    assert table.partitions[0].name == "2019"
    assert table.partitions[1].name == "2020"

    with freezegun.freeze_time("2019-12-30"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, years=1, count=3)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 3
    assert table.partitions[0].name == "2019"
    assert table.partitions[1].name == "2020"
    assert table.partitions[2].name == "2021"
コード例 #4
0
def test_partitioning_time_monthly_apply():
    """Tests whether automatically creating new partitions ahead monthly works
    as expected."""

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    # create partitions for the next 12 months (including the current)
    with freezegun.freeze_time("2019-1-30"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, months=1, count=12)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 12
    assert table.partitions[0].name == "2019_jan"
    assert table.partitions[1].name == "2019_feb"
    assert table.partitions[2].name == "2019_mar"
    assert table.partitions[3].name == "2019_apr"
    assert table.partitions[4].name == "2019_may"
    assert table.partitions[5].name == "2019_jun"
    assert table.partitions[6].name == "2019_jul"
    assert table.partitions[7].name == "2019_aug"
    assert table.partitions[8].name == "2019_sep"
    assert table.partitions[9].name == "2019_oct"
    assert table.partitions[10].name == "2019_nov"
    assert table.partitions[11].name == "2019_dec"

    # re-running it with 13, should just create one additional partition
    with freezegun.freeze_time("2019-1-30"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, months=1, count=13)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 13
    assert table.partitions[12].name == "2020_jan"

    # it's november now, we only want to create 4 partitions ahead,
    # so only one new partition should be created for february 1338
    with freezegun.freeze_time("2019-11-1"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, months=1, count=4)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 14
    assert table.partitions[13].name == "2020_feb"
コード例 #5
0
def test_partitioning_time_delete_ignore_manual():
    """Tests whether partitions that were created manually are ignored.

    Partitions created automatically have a special comment attached to
    them. Only partitions with this special comments would be deleted.
    """

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    manager = PostgresPartitioningManager(
        [partition_by_current_time(model, count=2, months=1)])

    schema_editor.add_range_partition(model,
                                      "2019_jan",
                                      from_values="2019-1-1",
                                      to_values="2019-2-1")

    with freezegun.freeze_time("2020-1-1"):
        manager.plan(skip_create=True).apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 1
コード例 #6
0
def test_partitioning_time_daily_apply():
    """Tests whether automatically creating new partitions ahead daily works as
    expected."""

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    # create partitions for the next 4 days (including the current)
    with freezegun.freeze_time("2019-1-23"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, days=1, count=4)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 4
    assert table.partitions[0].name == "2019_jan_23"
    assert table.partitions[1].name == "2019_jan_24"
    assert table.partitions[2].name == "2019_jan_25"
    assert table.partitions[3].name == "2019_jan_26"

    # re-running it with 5, should just create one additional partition
    with freezegun.freeze_time("2019-1-23"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, days=1, count=5)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 5
    assert table.partitions[4].name == "2019_jan_27"

    # it's june now, we want to partition two days ahead
    with freezegun.freeze_time("2019-06-03"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, days=1, count=2)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 7
    assert table.partitions[5].name == "2019_jun_03"
    assert table.partitions[6].name == "2019_jun_04"
コード例 #7
0
def test_partitioning_manager_plan_not_partitioned_model():
    """Tests that the auto partitioner does not try to auto partition for non-
    partitioned models/tables."""

    model = get_fake_model({"timestamp": models.DateTimeField()})

    with pytest.raises(PostgresPartitioningError):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, months=1, count=2)]
        )
        manager.plan()
コード例 #8
0
def test_partitioning_time_multiple(kwargs, partition_names):
    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    with freezegun.freeze_time("2019-1-1"):
        manager = PostgresPartitioningManager(
            [partition_by_current_time(model, **kwargs, count=2)])
        manager.plan().apply()

    table = _get_partitioned_table(model)
    assert len(table.partitions) == 2
    assert partition_names == [par.name for par in table.partitions]
コード例 #9
0
def test_partitioning_manager_duplicate_model():
    """Tests whether it is not possible to have more than one partitioning
    config per model."""

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]}
    )

    with pytest.raises(PostgresPartitioningError):
        PostgresPartitioningManager(
            [
                partition_by_current_time(model, years=1, count=3),
                partition_by_current_time(model, years=1, count=3),
            ]
        )
コード例 #10
0
def test_partitioning_manager_find_config_for_model():
    """Tests that finding a partitioning config by the model works as
    expected."""

    model1 = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]}
    )

    config1 = partition_by_current_time(model1, years=1, count=3)

    model2 = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]}
    )

    config2 = partition_by_current_time(model2, months=1, count=2)

    manager = PostgresPartitioningManager([config1, config2])
    assert manager.find_config_for_model(model1) == config1
    assert manager.find_config_for_model(model2) == config2
コード例 #11
0
def test_partitioning_time_delete(kwargs, timepoints):
    """Tests whether partitions older than the specified max_age are
    automatically deleted."""

    model = define_fake_partitioned_model(
        {"timestamp": models.DateTimeField()}, {"key": ["timestamp"]})

    schema_editor = connection.schema_editor()
    schema_editor.create_partitioned_model(model)

    partition_kwargs = {"model": model, "count": 6, **kwargs}

    manager = PostgresPartitioningManager(
        [partition_by_current_time(**partition_kwargs)])

    with freezegun.freeze_time(timepoints[0][0]):
        manager.plan().apply()

    for index, (dt, partition_count) in enumerate(timepoints):
        with freezegun.freeze_time(dt):
            manager.plan(skip_create=True).apply()

            table = _get_partitioned_table(model)
            assert len(table.partitions) == partition_count
コード例 #12
0
def fake_partitioning_manager(fake_model, fake_strategy):
    manager = PostgresPartitioningManager(
        [PostgresPartitioningConfig(fake_model, fake_strategy)])

    with override_settings(PSQLEXTRA_PARTITIONING_MANAGER=manager):
        yield manager