9
9
log = logging .getLogger ("django_pgviews.sync_pgviews" )
10
10
11
11
12
- class ViewSyncer (object ):
13
- def run (self , force , update , materialized_views_check_sql_changed = False , ** options ):
14
- self .synced = []
12
+ class RunBacklog (object ):
13
+ def __init__ (self ) -> None :
14
+ super ().__init__ ()
15
+ self .finished = []
16
+
17
+ def run (self , ** kwargs ):
18
+ self .finished = []
15
19
backlog = []
16
20
for view_cls in apps .get_models ():
17
21
if not (isinstance (view_cls , type ) and issubclass (view_cls , View ) and hasattr (view_cls , "sql" )):
@@ -20,30 +24,44 @@ def run(self, force, update, materialized_views_check_sql_changed=False, **optio
20
24
loop = 0
21
25
while len (backlog ) > 0 and loop < 10 :
22
26
loop += 1
23
- backlog = self .run_backlog (backlog , force , update , materialized_views_check_sql_changed )
27
+ backlog = self .run_backlog (backlog , ** kwargs )
24
28
25
29
if loop >= 10 :
26
30
log .warning ("pgviews dependencies hit limit. Check if your model dependencies are correct" )
27
- else :
31
+ return False
32
+
33
+ return True
34
+
35
+ def run_backlog (self , backlog , ** kwargs ):
36
+ raise NotImplementedError
37
+
38
+
39
+ class ViewSyncer (RunBacklog ):
40
+ def run (self , force , update , materialized_views_check_sql_changed = False , ** options ):
41
+ if super ().run (
42
+ force = force , update = update , materialized_views_check_sql_changed = materialized_views_check_sql_changed
43
+ ):
28
44
all_views_synced .send (sender = None )
29
45
30
- def run_backlog (self , models , force , update , materialized_views_check_sql_changed ):
46
+ def run_backlog (self , backlog , * , force , update , materialized_views_check_sql_changed , ** kwargs ):
31
47
"""Installs the list of models given from the previous backlog
32
48
33
49
If the correct dependent views have not been installed, the view
34
50
will be added to the backlog.
35
51
36
52
Eventually we get to a point where all dependencies are sorted.
37
53
"""
38
- backlog = []
39
- for view_cls in models :
54
+ new_backlog = []
55
+ for view_cls in backlog :
40
56
skip = False
41
57
name = "{}.{}" .format (view_cls ._meta .app_label , view_cls .__name__ )
42
58
for dep in view_cls ._dependencies :
43
- if dep not in self .synced :
59
+ if dep not in self .finished :
44
60
skip = True
61
+ break
62
+
45
63
if skip is True :
46
- backlog .append (view_cls )
64
+ new_backlog .append (view_cls )
47
65
log .info ("Putting pgview at back of queue: %s" , name )
48
66
continue # Skip
49
67
@@ -73,7 +91,7 @@ def run_backlog(self, models, force, update, materialized_views_check_sql_change
73
91
status = status ,
74
92
has_changed = status not in ("EXISTS" , "FORCE_REQUIRED" ),
75
93
)
76
- self .synced .append (name )
94
+ self .finished .append (name )
77
95
except Exception as exc :
78
96
exc .view_cls = view_cls
79
97
exc .python_name = name
@@ -93,4 +111,32 @@ def run_backlog(self, models, force, update, materialized_views_check_sql_change
93
111
msg = status
94
112
95
113
log .info ("pgview %s %s" , name , msg )
96
- return backlog
114
+ return new_backlog
115
+
116
+
117
+ class ViewRefresher (RunBacklog ):
118
+ def run (self , concurrently , ** kwargs ):
119
+ return super ().run (concurrently = concurrently , ** kwargs )
120
+
121
+ def run_backlog (self , backlog , * , concurrently , ** kwargs ):
122
+ new_backlog = []
123
+ for view_cls in backlog :
124
+ skip = False
125
+ name = "{}.{}" .format (view_cls ._meta .app_label , view_cls .__name__ )
126
+ for dep in view_cls ._dependencies :
127
+ if dep not in self .finished :
128
+ skip = True
129
+ break
130
+
131
+ if skip is True :
132
+ new_backlog .append (view_cls )
133
+ log .info ("Putting pgview at back of queue: %s" , name )
134
+ continue # Skip
135
+
136
+ if issubclass (view_cls , MaterializedView ):
137
+ view_cls .refresh (concurrently = concurrently )
138
+ log .info ("pgview %s refreshed" , name )
139
+
140
+ self .finished .append (name )
141
+
142
+ return new_backlog
0 commit comments