diff --git a/django_pgviews/apps.py b/django_pgviews/apps.py index 65aa994..7f40901 100644 --- a/django_pgviews/apps.py +++ b/django_pgviews/apps.py @@ -15,7 +15,7 @@ class ViewConfig(apps.AppConfig): name = "django_pgviews" verbose_name = "Django Postgres Views" - def sync_pgviews(self, sender, app_config, **kwargs): + def sync_pgviews(self, sender, app_config, using, **kwargs): """Forcibly sync the views. """ self.counter = self.counter + 1 @@ -28,7 +28,7 @@ def sync_pgviews(self, sender, app_config, **kwargs): from .models import ViewSyncer vs = ViewSyncer() - vs.run(force=True, update=True) + vs.run(force=True, update=True, using=using) def ready(self): """Find and setup the apps to set the post_migrate hooks for. diff --git a/django_pgviews/management/commands/clear_pgviews.py b/django_pgviews/management/commands/clear_pgviews.py index e11b0ca..a86ed4d 100644 --- a/django_pgviews/management/commands/clear_pgviews.py +++ b/django_pgviews/management/commands/clear_pgviews.py @@ -2,7 +2,7 @@ from django.core.management.base import BaseCommand from django.apps import apps -from django.db import connection +from django.db import DEFAULT_DB_ALIAS, connections from django_pgviews.view import clear_view, View, MaterializedView @@ -13,9 +13,19 @@ class Command(BaseCommand): help = """Clear Postgres views. Use this before running a migration""" + def add_arguments(self, parser): + parser.add_argument( + "--database", + default=DEFAULT_DB_ALIAS, + help='Nominates a database to synchronize. Defaults to the "default" database.', + ) + def handle(self, **options): """ """ + # Get the database we're operating from + db = options["database"] + connection = connections[db] for view_cls in apps.get_models(): if not (isinstance(view_cls, type) and issubclass(view_cls, View) and hasattr(view_cls, "sql")): continue diff --git a/django_pgviews/management/commands/sync_pgviews.py b/django_pgviews/management/commands/sync_pgviews.py index fbd361a..ede276f 100644 --- a/django_pgviews/management/commands/sync_pgviews.py +++ b/django_pgviews/management/commands/sync_pgviews.py @@ -2,8 +2,7 @@ import logging from django.core.management.base import BaseCommand -from django.db import connection -from django.apps import apps +from django.db import DEFAULT_DB_ALIAS from django_pgviews.models import ViewSyncer @@ -30,7 +29,12 @@ def add_arguments(self, parser): help="""Force replacement of pre-existing views where breaking changes have been made to the schema.""", ) + parser.add_argument( + "--database", + default=DEFAULT_DB_ALIAS, + help='Nominates a database to synchronize. Defaults to the "default" database.', + ) - def handle(self, force, update, **options): + def handle(self, force, update, database, **options): vs = ViewSyncer() - vs.run(force, update) + vs.run(force, update, using=database) diff --git a/django_pgviews/models.py b/django_pgviews/models.py index 73715ae..07c5a81 100644 --- a/django_pgviews/models.py +++ b/django_pgviews/models.py @@ -1,7 +1,7 @@ import logging from django.apps import apps -from django.db import connection +from django.db import connections, DEFAULT_DB_ALIAS from django_pgviews.view import create_view, View, MaterializedView from django_pgviews.signals import view_synced, all_views_synced @@ -10,7 +10,7 @@ class ViewSyncer(object): - def run(self, force, update, **options): + def run(self, force, update, using, **options): self.synced = [] backlog = [] for view_cls in apps.get_models(): @@ -20,14 +20,14 @@ def run(self, force, update, **options): loop = 0 while len(backlog) > 0 and loop < 10: loop += 1 - backlog = self.run_backlog(backlog, force, update) + backlog = self.run_backlog(backlog, force, update, using) if loop >= 10: log.warn("pgviews dependencies hit limit. Check if your model dependencies are correct") else: - all_views_synced.send(sender=None) + all_views_synced.send(sender=None, using=using) - def run_backlog(self, models, force, update): + def run_backlog(self, models, force, update, using=DEFAULT_DB_ALIAS): """Installs the list of models given from the previous backlog If the correct dependent views have not been installed, the view @@ -35,6 +35,7 @@ def run_backlog(self, models, force, update): Eventually we get to a point where all dependencies are sorted. """ + connection = connections[using] backlog = [] for view_cls in models: skip = False @@ -63,6 +64,7 @@ def run_backlog(self, models, force, update): force=force, status=status, has_changed=status not in ("EXISTS", "FORCE_REQUIRED"), + using=using, ) self.synced.append(name) except Exception as exc: diff --git a/django_pgviews/signals.py b/django_pgviews/signals.py index 50d5265..876b9c5 100644 --- a/django_pgviews/signals.py +++ b/django_pgviews/signals.py @@ -1,5 +1,5 @@ from django.dispatch import Signal -view_synced = Signal(providing_args=["update", "force", "status", "has_changed"]) +view_synced = Signal(providing_args=["update", "force", "status", "has_changed", "using"]) all_views_synced = Signal() diff --git a/django_pgviews/view.py b/django_pgviews/view.py index 9d67852..ec4ecb7 100644 --- a/django_pgviews/view.py +++ b/django_pgviews/view.py @@ -56,7 +56,7 @@ def realize_deferred_projections(sender, *args, **kwargs): # attribute or explicitly-defined field with that name. if hasattr(view_cls, name) or hasfield(view_cls, name): continue - copy.copy(field).contribute_to_class(view_cls, name) + copy.deepcopy(field).contribute_to_class(view_cls, name) models.signals.class_prepared.connect(realize_deferred_projections)