@@ -26,6 +26,7 @@ def __init__(self, model=None, query=None, using=None, hints=None):
2626
2727 self .conflict_target = None
2828 self .conflict_action = None
29+ self .index_predicate = None
2930
3031 def annotate (self , ** annotations ):
3132 """Custom version of the standard annotate function
@@ -113,7 +114,7 @@ def update(self, **fields):
113114 # affected, let's do the same
114115 return len (rows )
115116
116- def on_conflict (self , fields : List [Union [str , Tuple [str ]]], action ):
117+ def on_conflict (self , fields : List [Union [str , Tuple [str ]]], action , index_predicate : str = None ):
117118 """Sets the action to take when conflicts arise when attempting
118119 to insert/create a new row.
119120
@@ -123,10 +124,16 @@ def on_conflict(self, fields: List[Union[str, Tuple[str]]], action):
123124
124125 action:
125126 The action to take when the conflict occurs.
127+
128+ index_predicate:
129+ The index predicate to satisfy an arbiter partial index (i.e. what partial index to use for checking
130+ conflicts)
126131 """
127132
128133 self .conflict_target = fields
129134 self .conflict_action = action
135+ self .index_predicate = index_predicate
136+
130137 return self
131138
132139 def bulk_insert (self , rows ):
@@ -216,7 +223,7 @@ def insert_and_get(self, **fields):
216223
217224 return self .model (** model_init_fields )
218225
219- def upsert (self , conflict_target : List , fields : Dict ) -> int :
226+ def upsert (self , conflict_target : List , fields : Dict , index_predicate : str = None ) -> int :
220227 """Creates a new record or updates the existing one
221228 with the specified data.
222229
@@ -227,11 +234,15 @@ def upsert(self, conflict_target: List, fields: Dict) -> int:
227234 fields:
228235 Fields to insert/update.
229236
237+ index_predicate:
238+ The index predicate to satisfy an arbiter partial index (i.e. what partial index to use for checking
239+ conflicts)
240+
230241 Returns:
231242 The primary key of the row that was created/updated.
232243 """
233244
234- self .on_conflict (conflict_target , ConflictAction .UPDATE )
245+ self .on_conflict (conflict_target , ConflictAction .UPDATE , index_predicate )
235246 return self .insert (** fields )
236247
237248 def upsert_and_get (self , conflict_target : List , fields : Dict ):
@@ -307,6 +318,7 @@ def _build_insert_compiler(self, rows: List[Dict]):
307318 query = PostgresInsertQuery (self .model )
308319 query .conflict_action = self .conflict_action
309320 query .conflict_target = self .conflict_target
321+ query .index_predicate = self .index_predicate
310322 query .values (objs , insert_fields , update_fields )
311323
312324 # use the postgresql insert query compiler to transform the insert
@@ -466,7 +478,7 @@ def on_conflict(self, fields: List[Union[str, Tuple[str]]], action):
466478 """
467479 return self .get_queryset ().on_conflict (fields , action )
468480
469- def upsert (self , conflict_target : List , fields : Dict ) -> int :
481+ def upsert (self , conflict_target : List , fields : Dict , index_predicate : str = None ) -> int :
470482 """Creates a new record or updates the existing one
471483 with the specified data.
472484
@@ -477,11 +489,14 @@ def upsert(self, conflict_target: List, fields: Dict) -> int:
477489 fields:
478490 Fields to insert/update.
479491
492+ index_predicate:
493+ The index predicate to satisfy an arbiter partial index.
494+
480495 Returns:
481496 The primary key of the row that was created/updated.
482497 """
483498
484- return self .get_queryset ().upsert (conflict_target , fields )
499+ return self .get_queryset ().upsert (conflict_target , fields , index_predicate )
485500
486501 def upsert_and_get (self , conflict_target : List , fields : Dict ):
487502 """Creates a new record or updates the existing one
0 commit comments