partitioning.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. from typing import Dict, List, Type
  2. from psqlextra.models import PostgresPartitionedModel
  3. from .model import PostgresModelState
  4. class PostgresPartitionState:
  5. """Represents the state of a partition for a :see:PostgresPartitionedModel
  6. during a migration."""
  7. def __init__(self, app_label: str, model_name: str, name: str) -> None:
  8. self.app_label = app_label
  9. self.model_name = model_name
  10. self.name = name
  11. class PostgresRangePartitionState(PostgresPartitionState):
  12. """Represents the state of a range partition for a
  13. :see:PostgresPartitionedModel during a migration."""
  14. def __init__(
  15. self, app_label: str, model_name: str, name: str, from_values, to_values
  16. ):
  17. super().__init__(app_label, model_name, name)
  18. self.from_values = from_values
  19. self.to_values = to_values
  20. class PostgresListPartitionState(PostgresPartitionState):
  21. """Represents the state of a list partition for a
  22. :see:PostgresPartitionedModel during a migration."""
  23. def __init__(self, app_label: str, model_name: str, name: str, values):
  24. super().__init__(app_label, model_name, name)
  25. self.values = values
  26. class PostgresHashPartitionState(PostgresPartitionState):
  27. """Represents the state of a hash partition for a
  28. :see:PostgresPartitionedModel during a migration."""
  29. def __init__(
  30. self,
  31. app_label: str,
  32. model_name: str,
  33. name: str,
  34. modulus: int,
  35. remainder: int,
  36. ):
  37. super().__init__(app_label, model_name, name)
  38. self.modulus = modulus
  39. self.remainder = remainder
  40. class PostgresPartitionedModelState(PostgresModelState):
  41. """Represents the state of a :see:PostgresPartitionedModel in the
  42. migrations."""
  43. def __init__(
  44. self,
  45. *args,
  46. partitions: List[PostgresPartitionState] = [],
  47. partitioning_options={},
  48. **kwargs
  49. ):
  50. """Initializes a new instance of :see:PostgresPartitionedModelState.
  51. Arguments:
  52. partitioning_options:
  53. Dictionary of options for partitioning.
  54. See: PostgresPartitionedModelMeta for a list.
  55. """
  56. super().__init__(*args, **kwargs)
  57. self.partitions: Dict[str, PostgresPartitionState] = {
  58. partition.name: partition for partition in partitions
  59. }
  60. self.partitioning_options = dict(partitioning_options)
  61. def add_partition(self, partition: PostgresPartitionState):
  62. """Adds a partition to this partitioned model state."""
  63. self.partitions[partition.name] = partition
  64. def delete_partition(self, name: str):
  65. """Deletes a partition from this partitioned model state."""
  66. del self.partitions[name]
  67. @classmethod
  68. def _pre_new( # type: ignore[override]
  69. cls,
  70. model: PostgresPartitionedModel,
  71. model_state: "PostgresPartitionedModelState",
  72. ) -> "PostgresPartitionedModelState":
  73. """Called when a new model state is created from the specified
  74. model."""
  75. model_state.partitions = dict()
  76. model_state.partitioning_options = dict(
  77. model._partitioning_meta.original_attrs
  78. )
  79. return model_state
  80. def _pre_clone( # type: ignore[override]
  81. self, model_state: "PostgresPartitionedModelState"
  82. ) -> "PostgresPartitionedModelState":
  83. """Called when this model state is cloned."""
  84. model_state.partitions = dict(self.partitions)
  85. model_state.partitioning_options = dict(self.partitioning_options)
  86. return model_state
  87. def _pre_render(self, name: str, bases, attributes):
  88. """Called when this model state is rendered into a model."""
  89. partitioning_meta = type(
  90. "PartitioningMeta", (), dict(self.partitioning_options)
  91. )
  92. return (
  93. name,
  94. bases,
  95. {**attributes, "PartitioningMeta": partitioning_meta},
  96. )
  97. @classmethod
  98. def _get_base_model_class(self) -> Type[PostgresPartitionedModel]:
  99. """Gets the class to use as a base class for rendered models."""
  100. return PostgresPartitionedModel