1111from django .core import exceptions
1212from django .db import connections , router , transaction
1313from django .db import models
14+ from django .db .backends .postgresql .schema import DatabaseSchemaEditor
1415from django .db .models .query import QuerySet
1516
1617from django_pgviews .db import get_fields_by_name
@@ -96,7 +97,8 @@ def _drop_mat_view(cursor, view_name):
9697
9798
9899def _concurrent_index_name (view_name , concurrent_index ):
99- return view_name + "_" + "_" .join ([s .strip () for s in concurrent_index .split ("," )]) + "_index"
100+ # replace . with _ in view_name in case the table is in a schema
101+ return view_name .replace ("." , "_" ) + "_" + "_" .join ([s .strip () for s in concurrent_index .split ("," )]) + "_index"
100102
101103
102104def _create_concurrent_index (cursor , view_name , concurrent_index ):
@@ -109,6 +111,21 @@ def _create_concurrent_index(cursor, view_name, concurrent_index):
109111 )
110112
111113
114+ class CustomSchemaEditor (DatabaseSchemaEditor ):
115+ def _create_index_sql (self , * args , ** kwargs ):
116+ """
117+ Override to handle indexes in custom schemas, when the schema is explicitly set.
118+ """
119+ statement = super ()._create_index_sql (* args , ** kwargs )
120+
121+ model = args [0 ]
122+
123+ if "." in model ._meta .db_table : # by default the table it's quoted, but we need it non-quoted
124+ statement .parts ["table" ] = model ._meta .db_table
125+
126+ return statement
127+
128+
112129def _ensure_indexes (connection , cursor , view_cls , schema_name_log ):
113130 """
114131 This function gets called when a materialized view is deemed not needing a re-create. That is however only a part
@@ -133,17 +150,19 @@ def _ensure_indexes(connection, cursor, view_cls, schema_name_log):
133150 concurrent_index_name = None
134151
135152 for index_name in existing_indexes - required_indexes :
136- cursor .execute (f"DROP INDEX { index_name } " )
153+ cursor .execute (f"DROP INDEX { vschema } . { index_name } " )
137154 logger .info ("pgview dropped index %s on view %s (%s)" , index_name , view_name , schema_name_log )
138155
156+ schema_editor : DatabaseSchemaEditor = CustomSchemaEditor (connection )
157+
139158 for index_name in required_indexes - existing_indexes :
140159 if index_name == concurrent_index_name :
141160 _create_concurrent_index (cursor , view_name , concurrent_index )
142161 logger .info ("pgview created concurrent index on view %s (%s)" , view_name , schema_name_log )
143162 else :
144163 for index in indexes :
145164 if index .name == index_name :
146- connection . schema_editor () .add_index (view_cls , index )
165+ schema_editor .add_index (view_cls , index )
147166 logger .info ("pgview created index %s on view %s (%s)" , index .name , view_name , schema_name_log )
148167 break
149168
@@ -218,7 +237,7 @@ def create_materialized_view(connection, view_cls, check_sql_changed=False):
218237 logger .info ("pgview created concurrent index on view %s (%s)" , view_name , schema_name_log )
219238
220239 if view_cls ._meta .indexes :
221- schema_editor = connection . schema_editor ( )
240+ schema_editor = CustomSchemaEditor ( connection )
222241
223242 for index in view_cls ._meta .indexes :
224243 schema_editor .add_index (view_cls , index )
0 commit comments