123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- import sys
- from typing import Optional
- from django.conf import settings
- from django.core.management.base import BaseCommand
- from django.utils.module_loading import import_string
- from psqlextra.partitioning import PostgresPartitioningError
- class Command(BaseCommand):
- """Create new partitions and delete old ones according to the configured
- partitioning strategies."""
- help = "Create new partitions and delete old ones using the configured partitioning manager. The PSQLEXTRA_PARTITIONING_MANAGER setting must be configured."
- def add_arguments(self, parser):
- parser.add_argument(
- "--dry",
- "-d",
- action="store_true",
- help="When specified, no partition will be created/deleted. Just a simulation.",
- required=False,
- default=False,
- )
- parser.add_argument(
- "--yes",
- "-y",
- action="store_true",
- help="Answer yes to all questions. WARNING: You will not be asked before deleting a partition.",
- required=False,
- default=False,
- )
- parser.add_argument(
- "--using",
- "-u",
- help="Optional name of the database connection to use.",
- default="default",
- )
- parser.add_argument(
- "--skip-create",
- action="store_true",
- help="Do not create partitions.",
- required=False,
- default=False,
- )
- parser.add_argument(
- "--skip-delete",
- action="store_true",
- help="Do not delete partitions.",
- required=False,
- default=False,
- )
- def handle( # type: ignore[override]
- self,
- dry: bool,
- yes: bool,
- using: Optional[str],
- skip_create: bool,
- skip_delete: bool,
- *args,
- **kwargs,
- ):
- partitioning_manager = self._partitioning_manager()
- plan = partitioning_manager.plan(
- skip_create=skip_create, skip_delete=skip_delete, using=using
- )
- creations_count = len(plan.creations)
- deletions_count = len(plan.deletions)
- if creations_count == 0 and deletions_count == 0:
- print("Nothing to be done.")
- return
- plan.print()
- if dry:
- return
- if not yes:
- sys.stdout.write("Do you want to proceed? (y/N) ")
- if not self._ask_for_confirmation():
- print("Operation aborted.")
- return
- plan.apply(using=using)
- print("Operations applied.")
- @staticmethod
- def _ask_for_confirmation() -> bool:
- answer = input("").lower()
- if not answer:
- return False
- if answer[0] == "y" or answer == "yes":
- return True
- return False
- @staticmethod
- def _partitioning_manager():
- partitioning_manager = getattr(
- settings, "PSQLEXTRA_PARTITIONING_MANAGER", None
- )
- if not partitioning_manager:
- raise PostgresPartitioningError(
- "You must configure the PSQLEXTRA_PARTITIONING_MANAGER setting "
- "for automatic partitioning to work."
- )
- if isinstance(partitioning_manager, str):
- partitioning_manager = import_string(partitioning_manager)
- return partitioning_manager
|