Source code for pg_partitioning.decorators
import logging
from typing import Type
from django.db import models
from pg_partitioning.manager import ListPartitionManager, TimeRangePartitionManager
logger = logging.getLogger(__name__)
class _PartitioningBase:
def __init__(self, partition_key: str, **options):
self.partition_key = partition_key
self.options = options
def __call__(self, model: Type[models.Model]):
if model._meta.abstract:
raise NotImplementedError("Decorative abstract model classes are not supported.")
[docs]class TimeRangePartitioning(_PartitioningBase):
"""Use this decorator to declare the database table corresponding to the model to be partitioned by time range.
Parameters:
partition_key(str): Partition field name of DateTimeField.
options: Currently supports the following keyword parameters:
- default_period(PeriodType): Default partition period.
- default_interval(int): Default detach partition interval.
- default_attach_tablespace(str): Default tablespace for attached tables.
- default_detach_tablespace(str): Default tablespace for attached tables.
Example:
.. code-block:: python
from django.db import models
from django.utils import timezone
from pg_partitioning.decorators import TimeRangePartitioning
@TimeRangePartitioning(partition_key="timestamp")
class MyLog(models.Model):
name = models.TextField(default="Hello World!")
timestamp = models.DateTimeField(default=timezone.now, primary_key=True)
"""
def __call__(self, model: Type[models.Model]):
super().__call__(model)
if model._meta.get_field(self.partition_key).get_internal_type() != models.DateTimeField().get_internal_type():
raise ValueError("The partition_key must be DateTimeField type.")
model.partitioning = TimeRangePartitionManager(model, self.partition_key, self.options)
return model
[docs]class ListPartitioning(_PartitioningBase):
"""Use this decorator to declare the database table corresponding to the model to be partitioned by list.
Parameters:
partition_key(str): Partition key name, the type of the key must be one of boolean, text or integer.
Example:
.. code-block:: python
from django.db import models
from django.utils import timezone
from pg_partitioning.decorators import ListPartitioning
@ListPartitioning(partition_key="category")
class MyLog(models.Model):
category = models.TextField(default="A")
timestamp = models.DateTimeField(default=timezone.now, primary_key=True)
"""
def __call__(self, model: Type[models.Model]):
super().__call__(model)
support_field_types = [item.get_internal_type() for item in [models.TextField(), models.BooleanField(), models.IntegerField()]]
if model._meta.get_field(self.partition_key).get_internal_type() not in support_field_types:
raise NotImplementedError("The partition_key does not support this field type.")
model.partitioning = ListPartitionManager(model, self.partition_key, self.options)
return model