create_partitioned_model.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from django.db.migrations.operations.models import CreateModel
  2. from psqlextra.backend.migrations.state import PostgresPartitionedModelState
  3. class PostgresCreatePartitionedModel(CreateModel):
  4. """Creates the model as a native PostgreSQL 11.x partitioned table."""
  5. serialization_expand_args = [
  6. "fields",
  7. "options",
  8. "managers",
  9. "partitioning_options",
  10. ]
  11. def __init__(
  12. self,
  13. name,
  14. fields,
  15. options=None,
  16. partitioning_options={},
  17. bases=None,
  18. managers=None,
  19. ):
  20. super().__init__(name, fields, options, bases, managers)
  21. self.partitioning_options = partitioning_options or {}
  22. def state_forwards(self, app_label, state):
  23. state.add_model(
  24. PostgresPartitionedModelState(
  25. app_label=app_label,
  26. name=self.name,
  27. fields=list(self.fields),
  28. options=dict(self.options),
  29. bases=tuple(self.bases),
  30. managers=list(self.managers),
  31. partitioning_options=dict(self.partitioning_options),
  32. )
  33. )
  34. def database_forwards(self, app_label, schema_editor, from_state, to_state):
  35. """Apply this migration operation forwards."""
  36. model = to_state.apps.get_model(app_label, self.name)
  37. if self.allow_migrate_model(schema_editor.connection.alias, model):
  38. schema_editor.create_partitioned_model(model)
  39. def database_backwards(
  40. self, app_label, schema_editor, from_state, to_state
  41. ):
  42. """Apply this migration operation backwards."""
  43. model = from_state.apps.get_model(app_label, self.name)
  44. if self.allow_migrate_model(schema_editor.connection.alias, model):
  45. schema_editor.delete_partitioned_model(model)
  46. def deconstruct(self):
  47. name, args, kwargs = super().deconstruct()
  48. if self.partitioning_options:
  49. kwargs["partitioning_options"] = self.partitioning_options
  50. return name, args, kwargs
  51. def describe(self):
  52. """Gets a human readable text describing this migration."""
  53. description = super().describe()
  54. description = description.replace("model", "partitioned model")
  55. return description
  56. def reduce(self, *args, **kwargs):
  57. result = super().reduce(*args, **kwargs)
  58. # replace CreateModel operation with PostgresCreatePartitionedModel
  59. if isinstance(result, list) and result:
  60. for i, op in enumerate(result):
  61. if isinstance(op, CreateModel):
  62. _, args, kwargs = op.deconstruct()
  63. result[i] = PostgresCreatePartitionedModel(
  64. *args,
  65. **kwargs,
  66. partitioning_options=self.partitioning_options
  67. )
  68. return result