MCPcopy
hub / github.com/django/django / pre_sql_setup

Method pre_sql_setup

django/db/models/sql/compiler.py:2166–2229  ·  view source on GitHub ↗

If the update depends on results from other tables, munge the "where" conditions to match the format required for (portable) SQL updates. If multiple updates are required, pull out the id values to update at this point so that they don't change as a result of the pr

(self)

Source from the content-addressed store, hash-verified

2164 return list(rows)
2165
2166 def pre_sql_setup(self):
2167 """
2168 If the update depends on results from other tables, munge the "where"
2169 conditions to match the format required for (portable) SQL updates.
2170
2171 If multiple updates are required, pull out the id values to update at
2172 this point so that they don't change as a result of the progressive
2173 updates.
2174 """
2175 refcounts_before = self.query.alias_refcount.copy()
2176 # Ensure base table is in the query
2177 self.query.get_initial_alias()
2178 count = self.query.count_active_tables()
2179 if not self.query.related_updates and count == 1:
2180 return
2181 query = self.query.chain(klass=Query)
2182 query.select_related = False
2183 query.clear_ordering(force=True)
2184 query.extra = {}
2185 query.select = []
2186 meta = query.get_meta()
2187 fields = [meta.pk.name]
2188 related_ids_index = []
2189 for related in self.query.related_updates:
2190 if all(
2191 path.join_field.primary_key for path in meta.get_path_to_parent(related)
2192 ):
2193 # If a primary key chain exists to the targeted related update,
2194 # then the meta.pk value can be used for it.
2195 related_ids_index.append((related, 0))
2196 else:
2197 # This branch will only be reached when updating a field of an
2198 # ancestor that is not part of the primary key chain of a MTI
2199 # tree.
2200 related_ids_index.append((related, len(fields)))
2201 fields.append(related._meta.pk.name)
2202 query.add_fields(fields)
2203 super().pre_sql_setup()
2204
2205 is_composite_pk = meta.is_composite_pk
2206 must_pre_select = (
2207 count > 1 and not self.connection.features.update_can_self_select
2208 )
2209
2210 # Now we adjust the current query: reset the where clause and get rid
2211 # of all the tables we don't need (since they're in the sub-select).
2212 self.query.clear_where()
2213 if self.query.related_updates or must_pre_select:
2214 # Either we're using the idents in multiple update queries (so
2215 # don't want them to change), or the db backend doesn't support
2216 # selecting from the updating table (e.g. MySQL).
2217 idents = []
2218 related_ids = collections.defaultdict(list)
2219 for rows in query.get_compiler(self.using).execute_sql(MULTI):
2220 pks = [row if is_composite_pk else row[0] for row in rows]
2221 idents.extend(pks)
2222 for parent, index in related_ids_index:
2223 related_ids[parent].extend(r[index] for r in rows)

Callers 1

as_sqlMethod · 0.95

Calls 15

get_initial_aliasMethod · 0.80
count_active_tablesMethod · 0.80
clear_orderingMethod · 0.80
get_path_to_parentMethod · 0.80
clear_whereMethod · 0.80
get_compilerMethod · 0.80
extendMethod · 0.80
add_filterMethod · 0.80
reset_refcountsMethod · 0.80
copyMethod · 0.45
chainMethod · 0.45
get_metaMethod · 0.45

Tested by

no test coverage detected