You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

schema.py 53KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  1. import logging
  2. from datetime import datetime
  3. from django.db.backends.ddl_references import (
  4. Columns, ForeignKeyName, IndexName, Statement, Table,
  5. )
  6. from django.db.backends.utils import names_digest, split_identifier
  7. from django.db.models import Index
  8. from django.db.transaction import TransactionManagementError, atomic
  9. from django.utils import timezone
  10. logger = logging.getLogger('django.db.backends.schema')
  11. def _is_relevant_relation(relation, altered_field):
  12. """
  13. When altering the given field, must constraints on its model from the given
  14. relation be temporarily dropped?
  15. """
  16. field = relation.field
  17. if field.many_to_many:
  18. # M2M reverse field
  19. return False
  20. if altered_field.primary_key and field.to_fields == [None]:
  21. # Foreign key constraint on the primary key, which is being altered.
  22. return True
  23. # Is the constraint targeting the field being altered?
  24. return altered_field.name in field.to_fields
  25. def _related_non_m2m_objects(old_field, new_field):
  26. # Filter out m2m objects from reverse relations.
  27. # Return (old_relation, new_relation) tuples.
  28. return zip(
  29. (obj for obj in old_field.model._meta.related_objects if _is_relevant_relation(obj, old_field)),
  30. (obj for obj in new_field.model._meta.related_objects if _is_relevant_relation(obj, new_field))
  31. )
  32. class BaseDatabaseSchemaEditor:
  33. """
  34. This class and its subclasses are responsible for emitting schema-changing
  35. statements to the databases - model creation/removal/alteration, field
  36. renaming, index fiddling, and so on.
  37. """
  38. # Overrideable SQL templates
  39. sql_create_table = "CREATE TABLE %(table)s (%(definition)s)"
  40. sql_rename_table = "ALTER TABLE %(old_table)s RENAME TO %(new_table)s"
  41. sql_retablespace_table = "ALTER TABLE %(table)s SET TABLESPACE %(new_tablespace)s"
  42. sql_delete_table = "DROP TABLE %(table)s CASCADE"
  43. sql_create_column = "ALTER TABLE %(table)s ADD COLUMN %(column)s %(definition)s"
  44. sql_alter_column = "ALTER TABLE %(table)s %(changes)s"
  45. sql_alter_column_type = "ALTER COLUMN %(column)s TYPE %(type)s"
  46. sql_alter_column_null = "ALTER COLUMN %(column)s DROP NOT NULL"
  47. sql_alter_column_not_null = "ALTER COLUMN %(column)s SET NOT NULL"
  48. sql_alter_column_default = "ALTER COLUMN %(column)s SET DEFAULT %(default)s"
  49. sql_alter_column_no_default = "ALTER COLUMN %(column)s DROP DEFAULT"
  50. sql_delete_column = "ALTER TABLE %(table)s DROP COLUMN %(column)s CASCADE"
  51. sql_rename_column = "ALTER TABLE %(table)s RENAME COLUMN %(old_column)s TO %(new_column)s"
  52. sql_update_with_default = "UPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULL"
  53. sql_unique_constraint = "UNIQUE (%(columns)s)"
  54. sql_check_constraint = "CHECK (%(check)s)"
  55. sql_delete_constraint = "ALTER TABLE %(table)s DROP CONSTRAINT %(name)s"
  56. sql_constraint = "CONSTRAINT %(name)s %(constraint)s"
  57. sql_create_check = "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s CHECK (%(check)s)"
  58. sql_delete_check = sql_delete_constraint
  59. sql_create_unique = "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s UNIQUE (%(columns)s)"
  60. sql_delete_unique = sql_delete_constraint
  61. sql_create_fk = (
  62. "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) "
  63. "REFERENCES %(to_table)s (%(to_column)s)%(deferrable)s"
  64. )
  65. sql_create_inline_fk = None
  66. sql_delete_fk = sql_delete_constraint
  67. sql_create_index = "CREATE INDEX %(name)s ON %(table)s (%(columns)s)%(extra)s%(condition)s"
  68. sql_create_unique_index = "CREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)%(condition)s"
  69. sql_delete_index = "DROP INDEX %(name)s"
  70. sql_create_pk = "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s PRIMARY KEY (%(columns)s)"
  71. sql_delete_pk = sql_delete_constraint
  72. sql_delete_procedure = 'DROP PROCEDURE %(procedure)s'
  73. def __init__(self, connection, collect_sql=False, atomic=True):
  74. self.connection = connection
  75. self.collect_sql = collect_sql
  76. if self.collect_sql:
  77. self.collected_sql = []
  78. self.atomic_migration = self.connection.features.can_rollback_ddl and atomic
  79. # State-managing methods
  80. def __enter__(self):
  81. self.deferred_sql = []
  82. if self.atomic_migration:
  83. self.atomic = atomic(self.connection.alias)
  84. self.atomic.__enter__()
  85. return self
  86. def __exit__(self, exc_type, exc_value, traceback):
  87. if exc_type is None:
  88. for sql in self.deferred_sql:
  89. self.execute(sql)
  90. if self.atomic_migration:
  91. self.atomic.__exit__(exc_type, exc_value, traceback)
  92. # Core utility functions
  93. def execute(self, sql, params=()):
  94. """Execute the given SQL statement, with optional parameters."""
  95. # Don't perform the transactional DDL check if SQL is being collected
  96. # as it's not going to be executed anyway.
  97. if not self.collect_sql and self.connection.in_atomic_block and not self.connection.features.can_rollback_ddl:
  98. raise TransactionManagementError(
  99. "Executing DDL statements while in a transaction on databases "
  100. "that can't perform a rollback is prohibited."
  101. )
  102. # Account for non-string statement objects.
  103. sql = str(sql)
  104. # Log the command we're running, then run it
  105. logger.debug("%s; (params %r)", sql, params, extra={'params': params, 'sql': sql})
  106. if self.collect_sql:
  107. ending = "" if sql.endswith(";") else ";"
  108. if params is not None:
  109. self.collected_sql.append((sql % tuple(map(self.quote_value, params))) + ending)
  110. else:
  111. self.collected_sql.append(sql + ending)
  112. else:
  113. with self.connection.cursor() as cursor:
  114. cursor.execute(sql, params)
  115. def quote_name(self, name):
  116. return self.connection.ops.quote_name(name)
  117. # Field <-> database mapping functions
  118. def column_sql(self, model, field, include_default=False):
  119. """
  120. Take a field and return its column definition.
  121. The field must already have had set_attributes_from_name() called.
  122. """
  123. # Get the column's type and use that as the basis of the SQL
  124. db_params = field.db_parameters(connection=self.connection)
  125. sql = db_params['type']
  126. params = []
  127. # Check for fields that aren't actually columns (e.g. M2M)
  128. if sql is None:
  129. return None, None
  130. # Work out nullability
  131. null = field.null
  132. # If we were told to include a default value, do so
  133. include_default = include_default and not self.skip_default(field)
  134. if include_default:
  135. default_value = self.effective_default(field)
  136. if default_value is not None:
  137. if self.connection.features.requires_literal_defaults:
  138. # Some databases can't take defaults as a parameter (oracle)
  139. # If this is the case, the individual schema backend should
  140. # implement prepare_default
  141. sql += " DEFAULT %s" % self.prepare_default(default_value)
  142. else:
  143. sql += " DEFAULT %s"
  144. params += [default_value]
  145. # Oracle treats the empty string ('') as null, so coerce the null
  146. # option whenever '' is a possible value.
  147. if (field.empty_strings_allowed and not field.primary_key and
  148. self.connection.features.interprets_empty_strings_as_nulls):
  149. null = True
  150. if null and not self.connection.features.implied_column_null:
  151. sql += " NULL"
  152. elif not null:
  153. sql += " NOT NULL"
  154. # Primary key/unique outputs
  155. if field.primary_key:
  156. sql += " PRIMARY KEY"
  157. elif field.unique:
  158. sql += " UNIQUE"
  159. # Optionally add the tablespace if it's an implicitly indexed column
  160. tablespace = field.db_tablespace or model._meta.db_tablespace
  161. if tablespace and self.connection.features.supports_tablespaces and field.unique:
  162. sql += " %s" % self.connection.ops.tablespace_sql(tablespace, inline=True)
  163. # Return the sql
  164. return sql, params
  165. def skip_default(self, field):
  166. """
  167. Some backends don't accept default values for certain columns types
  168. (i.e. MySQL longtext and longblob).
  169. """
  170. return False
  171. def prepare_default(self, value):
  172. """
  173. Only used for backends which have requires_literal_defaults feature
  174. """
  175. raise NotImplementedError(
  176. 'subclasses of BaseDatabaseSchemaEditor for backends which have '
  177. 'requires_literal_defaults must provide a prepare_default() method'
  178. )
  179. @staticmethod
  180. def _effective_default(field):
  181. # This method allows testing its logic without a connection.
  182. if field.has_default():
  183. default = field.get_default()
  184. elif not field.null and field.blank and field.empty_strings_allowed:
  185. if field.get_internal_type() == "BinaryField":
  186. default = bytes()
  187. else:
  188. default = str()
  189. elif getattr(field, 'auto_now', False) or getattr(field, 'auto_now_add', False):
  190. default = datetime.now()
  191. internal_type = field.get_internal_type()
  192. if internal_type == 'DateField':
  193. default = default.date()
  194. elif internal_type == 'TimeField':
  195. default = default.time()
  196. elif internal_type == 'DateTimeField':
  197. default = timezone.now()
  198. else:
  199. default = None
  200. return default
  201. def effective_default(self, field):
  202. """Return a field's effective database default value."""
  203. return field.get_db_prep_save(self._effective_default(field), self.connection)
  204. def quote_value(self, value):
  205. """
  206. Return a quoted version of the value so it's safe to use in an SQL
  207. string. This is not safe against injection from user code; it is
  208. intended only for use in making SQL scripts or preparing default values
  209. for particularly tricky backends (defaults are not user-defined, though,
  210. so this is safe).
  211. """
  212. raise NotImplementedError()
  213. # Actions
  214. def create_model(self, model):
  215. """
  216. Create a table and any accompanying indexes or unique constraints for
  217. the given `model`.
  218. """
  219. # Create column SQL, add FK deferreds if needed
  220. column_sqls = []
  221. params = []
  222. for field in model._meta.local_fields:
  223. # SQL
  224. definition, extra_params = self.column_sql(model, field)
  225. if definition is None:
  226. continue
  227. # Check constraints can go on the column SQL here
  228. db_params = field.db_parameters(connection=self.connection)
  229. if db_params['check']:
  230. definition += " " + self.sql_check_constraint % db_params
  231. # Autoincrement SQL (for backends with inline variant)
  232. col_type_suffix = field.db_type_suffix(connection=self.connection)
  233. if col_type_suffix:
  234. definition += " %s" % col_type_suffix
  235. params.extend(extra_params)
  236. # FK
  237. if field.remote_field and field.db_constraint:
  238. to_table = field.remote_field.model._meta.db_table
  239. to_column = field.remote_field.model._meta.get_field(field.remote_field.field_name).column
  240. if self.sql_create_inline_fk:
  241. definition += " " + self.sql_create_inline_fk % {
  242. "to_table": self.quote_name(to_table),
  243. "to_column": self.quote_name(to_column),
  244. }
  245. elif self.connection.features.supports_foreign_keys:
  246. self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s"))
  247. # Add the SQL to our big list
  248. column_sqls.append("%s %s" % (
  249. self.quote_name(field.column),
  250. definition,
  251. ))
  252. # Autoincrement SQL (for backends with post table definition variant)
  253. if field.get_internal_type() in ("AutoField", "BigAutoField"):
  254. autoinc_sql = self.connection.ops.autoinc_sql(model._meta.db_table, field.column)
  255. if autoinc_sql:
  256. self.deferred_sql.extend(autoinc_sql)
  257. # Add any unique_togethers (always deferred, as some fields might be
  258. # created afterwards, like geometry fields with some backends)
  259. for fields in model._meta.unique_together:
  260. columns = [model._meta.get_field(field).column for field in fields]
  261. self.deferred_sql.append(self._create_unique_sql(model, columns))
  262. constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints]
  263. # Make the table
  264. sql = self.sql_create_table % {
  265. "table": self.quote_name(model._meta.db_table),
  266. "definition": ", ".join(constraint for constraint in (*column_sqls, *constraints) if constraint),
  267. }
  268. if model._meta.db_tablespace:
  269. tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
  270. if tablespace_sql:
  271. sql += ' ' + tablespace_sql
  272. # Prevent using [] as params, in the case a literal '%' is used in the definition
  273. self.execute(sql, params or None)
  274. # Add any field index and index_together's (deferred as SQLite _remake_table needs it)
  275. self.deferred_sql.extend(self._model_indexes_sql(model))
  276. # Make M2M tables
  277. for field in model._meta.local_many_to_many:
  278. if field.remote_field.through._meta.auto_created:
  279. self.create_model(field.remote_field.through)
  280. def delete_model(self, model):
  281. """Delete a model from the database."""
  282. # Handle auto-created intermediary models
  283. for field in model._meta.local_many_to_many:
  284. if field.remote_field.through._meta.auto_created:
  285. self.delete_model(field.remote_field.through)
  286. # Delete the table
  287. self.execute(self.sql_delete_table % {
  288. "table": self.quote_name(model._meta.db_table),
  289. })
  290. # Remove all deferred statements referencing the deleted table.
  291. for sql in list(self.deferred_sql):
  292. if isinstance(sql, Statement) and sql.references_table(model._meta.db_table):
  293. self.deferred_sql.remove(sql)
  294. def add_index(self, model, index):
  295. """Add an index on a model."""
  296. self.execute(index.create_sql(model, self), params=None)
  297. def remove_index(self, model, index):
  298. """Remove an index from a model."""
  299. self.execute(index.remove_sql(model, self))
  300. def add_constraint(self, model, constraint):
  301. """Add a check constraint to a model."""
  302. sql = constraint.create_sql(model, self)
  303. if sql:
  304. self.execute(sql)
  305. def remove_constraint(self, model, constraint):
  306. """Remove a check constraint from a model."""
  307. sql = constraint.remove_sql(model, self)
  308. if sql:
  309. self.execute(sql)
  310. def alter_unique_together(self, model, old_unique_together, new_unique_together):
  311. """
  312. Deal with a model changing its unique_together. The input
  313. unique_togethers must be doubly-nested, not the single-nested
  314. ["foo", "bar"] format.
  315. """
  316. olds = {tuple(fields) for fields in old_unique_together}
  317. news = {tuple(fields) for fields in new_unique_together}
  318. # Deleted uniques
  319. for fields in olds.difference(news):
  320. self._delete_composed_index(model, fields, {'unique': True}, self.sql_delete_unique)
  321. # Created uniques
  322. for fields in news.difference(olds):
  323. columns = [model._meta.get_field(field).column for field in fields]
  324. self.execute(self._create_unique_sql(model, columns))
  325. def alter_index_together(self, model, old_index_together, new_index_together):
  326. """
  327. Deal with a model changing its index_together. The input
  328. index_togethers must be doubly-nested, not the single-nested
  329. ["foo", "bar"] format.
  330. """
  331. olds = {tuple(fields) for fields in old_index_together}
  332. news = {tuple(fields) for fields in new_index_together}
  333. # Deleted indexes
  334. for fields in olds.difference(news):
  335. self._delete_composed_index(model, fields, {'index': True}, self.sql_delete_index)
  336. # Created indexes
  337. for field_names in news.difference(olds):
  338. fields = [model._meta.get_field(field) for field in field_names]
  339. self.execute(self._create_index_sql(model, fields, suffix="_idx"))
  340. def _delete_composed_index(self, model, fields, constraint_kwargs, sql):
  341. meta_constraint_names = {constraint.name for constraint in model._meta.constraints}
  342. meta_index_names = {constraint.name for constraint in model._meta.indexes}
  343. columns = [model._meta.get_field(field).column for field in fields]
  344. constraint_names = self._constraint_names(
  345. model, columns, exclude=meta_constraint_names | meta_index_names,
  346. **constraint_kwargs
  347. )
  348. if len(constraint_names) != 1:
  349. raise ValueError("Found wrong number (%s) of constraints for %s(%s)" % (
  350. len(constraint_names),
  351. model._meta.db_table,
  352. ", ".join(columns),
  353. ))
  354. self.execute(self._delete_constraint_sql(sql, model, constraint_names[0]))
  355. def alter_db_table(self, model, old_db_table, new_db_table):
  356. """Rename the table a model points to."""
  357. if (old_db_table == new_db_table or
  358. (self.connection.features.ignores_table_name_case and
  359. old_db_table.lower() == new_db_table.lower())):
  360. return
  361. self.execute(self.sql_rename_table % {
  362. "old_table": self.quote_name(old_db_table),
  363. "new_table": self.quote_name(new_db_table),
  364. })
  365. # Rename all references to the old table name.
  366. for sql in self.deferred_sql:
  367. if isinstance(sql, Statement):
  368. sql.rename_table_references(old_db_table, new_db_table)
  369. def alter_db_tablespace(self, model, old_db_tablespace, new_db_tablespace):
  370. """Move a model's table between tablespaces."""
  371. self.execute(self.sql_retablespace_table % {
  372. "table": self.quote_name(model._meta.db_table),
  373. "old_tablespace": self.quote_name(old_db_tablespace),
  374. "new_tablespace": self.quote_name(new_db_tablespace),
  375. })
  376. def add_field(self, model, field):
  377. """
  378. Create a field on a model. Usually involves adding a column, but may
  379. involve adding a table instead (for M2M fields).
  380. """
  381. # Special-case implicit M2M tables
  382. if field.many_to_many and field.remote_field.through._meta.auto_created:
  383. return self.create_model(field.remote_field.through)
  384. # Get the column's definition
  385. definition, params = self.column_sql(model, field, include_default=True)
  386. # It might not actually have a column behind it
  387. if definition is None:
  388. return
  389. # Check constraints can go on the column SQL here
  390. db_params = field.db_parameters(connection=self.connection)
  391. if db_params['check']:
  392. definition += " " + self.sql_check_constraint % db_params
  393. # Build the SQL and run it
  394. sql = self.sql_create_column % {
  395. "table": self.quote_name(model._meta.db_table),
  396. "column": self.quote_name(field.column),
  397. "definition": definition,
  398. }
  399. self.execute(sql, params)
  400. # Drop the default if we need to
  401. # (Django usually does not use in-database defaults)
  402. if not self.skip_default(field) and self.effective_default(field) is not None:
  403. changes_sql, params = self._alter_column_default_sql(model, None, field, drop=True)
  404. sql = self.sql_alter_column % {
  405. "table": self.quote_name(model._meta.db_table),
  406. "changes": changes_sql,
  407. }
  408. self.execute(sql, params)
  409. # Add an index, if required
  410. self.deferred_sql.extend(self._field_indexes_sql(model, field))
  411. # Add any FK constraints later
  412. if field.remote_field and self.connection.features.supports_foreign_keys and field.db_constraint:
  413. self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s"))
  414. # Reset connection if required
  415. if self.connection.features.connection_persists_old_columns:
  416. self.connection.close()
  417. def remove_field(self, model, field):
  418. """
  419. Remove a field from a model. Usually involves deleting a column,
  420. but for M2Ms may involve deleting a table.
  421. """
  422. # Special-case implicit M2M tables
  423. if field.many_to_many and field.remote_field.through._meta.auto_created:
  424. return self.delete_model(field.remote_field.through)
  425. # It might not actually have a column behind it
  426. if field.db_parameters(connection=self.connection)['type'] is None:
  427. return
  428. # Drop any FK constraints, MySQL requires explicit deletion
  429. if field.remote_field:
  430. fk_names = self._constraint_names(model, [field.column], foreign_key=True)
  431. for fk_name in fk_names:
  432. self.execute(self._delete_fk_sql(model, fk_name))
  433. # Delete the column
  434. sql = self.sql_delete_column % {
  435. "table": self.quote_name(model._meta.db_table),
  436. "column": self.quote_name(field.column),
  437. }
  438. self.execute(sql)
  439. # Reset connection if required
  440. if self.connection.features.connection_persists_old_columns:
  441. self.connection.close()
  442. # Remove all deferred statements referencing the deleted column.
  443. for sql in list(self.deferred_sql):
  444. if isinstance(sql, Statement) and sql.references_column(model._meta.db_table, field.column):
  445. self.deferred_sql.remove(sql)
  446. def alter_field(self, model, old_field, new_field, strict=False):
  447. """
  448. Allow a field's type, uniqueness, nullability, default, column,
  449. constraints, etc. to be modified.
  450. `old_field` is required to compute the necessary changes.
  451. If `strict` is True, raise errors if the old column does not match
  452. `old_field` precisely.
  453. """
  454. # Ensure this field is even column-based
  455. old_db_params = old_field.db_parameters(connection=self.connection)
  456. old_type = old_db_params['type']
  457. new_db_params = new_field.db_parameters(connection=self.connection)
  458. new_type = new_db_params['type']
  459. if ((old_type is None and old_field.remote_field is None) or
  460. (new_type is None and new_field.remote_field is None)):
  461. raise ValueError(
  462. "Cannot alter field %s into %s - they do not properly define "
  463. "db_type (are you using a badly-written custom field?)" %
  464. (old_field, new_field),
  465. )
  466. elif old_type is None and new_type is None and (
  467. old_field.remote_field.through and new_field.remote_field.through and
  468. old_field.remote_field.through._meta.auto_created and
  469. new_field.remote_field.through._meta.auto_created):
  470. return self._alter_many_to_many(model, old_field, new_field, strict)
  471. elif old_type is None and new_type is None and (
  472. old_field.remote_field.through and new_field.remote_field.through and
  473. not old_field.remote_field.through._meta.auto_created and
  474. not new_field.remote_field.through._meta.auto_created):
  475. # Both sides have through models; this is a no-op.
  476. return
  477. elif old_type is None or new_type is None:
  478. raise ValueError(
  479. "Cannot alter field %s into %s - they are not compatible types "
  480. "(you cannot alter to or from M2M fields, or add or remove "
  481. "through= on M2M fields)" % (old_field, new_field)
  482. )
  483. self._alter_field(model, old_field, new_field, old_type, new_type,
  484. old_db_params, new_db_params, strict)
  485. def _alter_field(self, model, old_field, new_field, old_type, new_type,
  486. old_db_params, new_db_params, strict=False):
  487. """Perform a "physical" (non-ManyToMany) field update."""
  488. # Drop any FK constraints, we'll remake them later
  489. fks_dropped = set()
  490. if old_field.remote_field and old_field.db_constraint:
  491. fk_names = self._constraint_names(model, [old_field.column], foreign_key=True)
  492. if strict and len(fk_names) != 1:
  493. raise ValueError("Found wrong number (%s) of foreign key constraints for %s.%s" % (
  494. len(fk_names),
  495. model._meta.db_table,
  496. old_field.column,
  497. ))
  498. for fk_name in fk_names:
  499. fks_dropped.add((old_field.column,))
  500. self.execute(self._delete_fk_sql(model, fk_name))
  501. # Has unique been removed?
  502. if old_field.unique and (not new_field.unique or self._field_became_primary_key(old_field, new_field)):
  503. # Find the unique constraint for this field
  504. meta_constraint_names = {constraint.name for constraint in model._meta.constraints}
  505. constraint_names = self._constraint_names(
  506. model, [old_field.column], unique=True, primary_key=False,
  507. exclude=meta_constraint_names,
  508. )
  509. if strict and len(constraint_names) != 1:
  510. raise ValueError("Found wrong number (%s) of unique constraints for %s.%s" % (
  511. len(constraint_names),
  512. model._meta.db_table,
  513. old_field.column,
  514. ))
  515. for constraint_name in constraint_names:
  516. self.execute(self._delete_unique_sql(model, constraint_name))
  517. # Drop incoming FK constraints if the field is a primary key or unique,
  518. # which might be a to_field target, and things are going to change.
  519. drop_foreign_keys = (
  520. (
  521. (old_field.primary_key and new_field.primary_key) or
  522. (old_field.unique and new_field.unique)
  523. ) and old_type != new_type
  524. )
  525. if drop_foreign_keys:
  526. # '_meta.related_field' also contains M2M reverse fields, these
  527. # will be filtered out
  528. for _old_rel, new_rel in _related_non_m2m_objects(old_field, new_field):
  529. rel_fk_names = self._constraint_names(
  530. new_rel.related_model, [new_rel.field.column], foreign_key=True
  531. )
  532. for fk_name in rel_fk_names:
  533. self.execute(self._delete_fk_sql(new_rel.related_model, fk_name))
  534. # Removed an index? (no strict check, as multiple indexes are possible)
  535. # Remove indexes if db_index switched to False or a unique constraint
  536. # will now be used in lieu of an index. The following lines from the
  537. # truth table show all True cases; the rest are False:
  538. #
  539. # old_field.db_index | old_field.unique | new_field.db_index | new_field.unique
  540. # ------------------------------------------------------------------------------
  541. # True | False | False | False
  542. # True | False | False | True
  543. # True | False | True | True
  544. if old_field.db_index and not old_field.unique and (not new_field.db_index or new_field.unique):
  545. # Find the index for this field
  546. meta_index_names = {index.name for index in model._meta.indexes}
  547. # Retrieve only BTREE indexes since this is what's created with
  548. # db_index=True.
  549. index_names = self._constraint_names(
  550. model, [old_field.column], index=True, type_=Index.suffix,
  551. exclude=meta_index_names,
  552. )
  553. for index_name in index_names:
  554. # The only way to check if an index was created with
  555. # db_index=True or with Index(['field'], name='foo')
  556. # is to look at its name (refs #28053).
  557. self.execute(self._delete_index_sql(model, index_name))
  558. # Change check constraints?
  559. if old_db_params['check'] != new_db_params['check'] and old_db_params['check']:
  560. meta_constraint_names = {constraint.name for constraint in model._meta.constraints}
  561. constraint_names = self._constraint_names(
  562. model, [old_field.column], check=True,
  563. exclude=meta_constraint_names,
  564. )
  565. if strict and len(constraint_names) != 1:
  566. raise ValueError("Found wrong number (%s) of check constraints for %s.%s" % (
  567. len(constraint_names),
  568. model._meta.db_table,
  569. old_field.column,
  570. ))
  571. for constraint_name in constraint_names:
  572. self.execute(self._delete_check_sql(model, constraint_name))
  573. # Have they renamed the column?
  574. if old_field.column != new_field.column:
  575. self.execute(self._rename_field_sql(model._meta.db_table, old_field, new_field, new_type))
  576. # Rename all references to the renamed column.
  577. for sql in self.deferred_sql:
  578. if isinstance(sql, Statement):
  579. sql.rename_column_references(model._meta.db_table, old_field.column, new_field.column)
  580. # Next, start accumulating actions to do
  581. actions = []
  582. null_actions = []
  583. post_actions = []
  584. # Type change?
  585. if old_type != new_type:
  586. fragment, other_actions = self._alter_column_type_sql(model, old_field, new_field, new_type)
  587. actions.append(fragment)
  588. post_actions.extend(other_actions)
  589. # When changing a column NULL constraint to NOT NULL with a given
  590. # default value, we need to perform 4 steps:
  591. # 1. Add a default for new incoming writes
  592. # 2. Update existing NULL rows with new default
  593. # 3. Replace NULL constraint with NOT NULL
  594. # 4. Drop the default again.
  595. # Default change?
  596. old_default = self.effective_default(old_field)
  597. new_default = self.effective_default(new_field)
  598. needs_database_default = (
  599. old_field.null and
  600. not new_field.null and
  601. old_default != new_default and
  602. new_default is not None and
  603. not self.skip_default(new_field)
  604. )
  605. if needs_database_default:
  606. actions.append(self._alter_column_default_sql(model, old_field, new_field))
  607. # Nullability change?
  608. if old_field.null != new_field.null:
  609. fragment = self._alter_column_null_sql(model, old_field, new_field)
  610. if fragment:
  611. null_actions.append(fragment)
  612. # Only if we have a default and there is a change from NULL to NOT NULL
  613. four_way_default_alteration = (
  614. new_field.has_default() and
  615. (old_field.null and not new_field.null)
  616. )
  617. if actions or null_actions:
  618. if not four_way_default_alteration:
  619. # If we don't have to do a 4-way default alteration we can
  620. # directly run a (NOT) NULL alteration
  621. actions = actions + null_actions
  622. # Combine actions together if we can (e.g. postgres)
  623. if self.connection.features.supports_combined_alters and actions:
  624. sql, params = tuple(zip(*actions))
  625. actions = [(", ".join(sql), sum(params, []))]
  626. # Apply those actions
  627. for sql, params in actions:
  628. self.execute(
  629. self.sql_alter_column % {
  630. "table": self.quote_name(model._meta.db_table),
  631. "changes": sql,
  632. },
  633. params,
  634. )
  635. if four_way_default_alteration:
  636. # Update existing rows with default value
  637. self.execute(
  638. self.sql_update_with_default % {
  639. "table": self.quote_name(model._meta.db_table),
  640. "column": self.quote_name(new_field.column),
  641. "default": "%s",
  642. },
  643. [new_default],
  644. )
  645. # Since we didn't run a NOT NULL change before we need to do it
  646. # now
  647. for sql, params in null_actions:
  648. self.execute(
  649. self.sql_alter_column % {
  650. "table": self.quote_name(model._meta.db_table),
  651. "changes": sql,
  652. },
  653. params,
  654. )
  655. if post_actions:
  656. for sql, params in post_actions:
  657. self.execute(sql, params)
  658. # If primary_key changed to False, delete the primary key constraint.
  659. if old_field.primary_key and not new_field.primary_key:
  660. self._delete_primary_key(model, strict)
  661. # Added a unique?
  662. if self._unique_should_be_added(old_field, new_field):
  663. self.execute(self._create_unique_sql(model, [new_field.column]))
  664. # Added an index? Add an index if db_index switched to True or a unique
  665. # constraint will no longer be used in lieu of an index. The following
  666. # lines from the truth table show all True cases; the rest are False:
  667. #
  668. # old_field.db_index | old_field.unique | new_field.db_index | new_field.unique
  669. # ------------------------------------------------------------------------------
  670. # False | False | True | False
  671. # False | True | True | False
  672. # True | True | True | False
  673. if (not old_field.db_index or old_field.unique) and new_field.db_index and not new_field.unique:
  674. self.execute(self._create_index_sql(model, [new_field]))
  675. # Type alteration on primary key? Then we need to alter the column
  676. # referring to us.
  677. rels_to_update = []
  678. if old_field.primary_key and new_field.primary_key and old_type != new_type:
  679. rels_to_update.extend(_related_non_m2m_objects(old_field, new_field))
  680. # Changed to become primary key?
  681. if self._field_became_primary_key(old_field, new_field):
  682. # Make the new one
  683. self.execute(self._create_primary_key_sql(model, new_field))
  684. # Update all referencing columns
  685. rels_to_update.extend(_related_non_m2m_objects(old_field, new_field))
  686. # Handle our type alters on the other end of rels from the PK stuff above
  687. for old_rel, new_rel in rels_to_update:
  688. rel_db_params = new_rel.field.db_parameters(connection=self.connection)
  689. rel_type = rel_db_params['type']
  690. fragment, other_actions = self._alter_column_type_sql(
  691. new_rel.related_model, old_rel.field, new_rel.field, rel_type
  692. )
  693. self.execute(
  694. self.sql_alter_column % {
  695. "table": self.quote_name(new_rel.related_model._meta.db_table),
  696. "changes": fragment[0],
  697. },
  698. fragment[1],
  699. )
  700. for sql, params in other_actions:
  701. self.execute(sql, params)
  702. # Does it have a foreign key?
  703. if (new_field.remote_field and
  704. (fks_dropped or not old_field.remote_field or not old_field.db_constraint) and
  705. new_field.db_constraint):
  706. self.execute(self._create_fk_sql(model, new_field, "_fk_%(to_table)s_%(to_column)s"))
  707. # Rebuild FKs that pointed to us if we previously had to drop them
  708. if drop_foreign_keys:
  709. for rel in new_field.model._meta.related_objects:
  710. if _is_relevant_relation(rel, new_field) and rel.field.db_constraint:
  711. self.execute(self._create_fk_sql(rel.related_model, rel.field, "_fk"))
  712. # Does it have check constraints we need to add?
  713. if old_db_params['check'] != new_db_params['check'] and new_db_params['check']:
  714. constraint_name = self._create_index_name(model._meta.db_table, [new_field.column], suffix='_check')
  715. self.execute(self._create_check_sql(model, constraint_name, new_db_params['check']))
  716. # Drop the default if we need to
  717. # (Django usually does not use in-database defaults)
  718. if needs_database_default:
  719. changes_sql, params = self._alter_column_default_sql(model, old_field, new_field, drop=True)
  720. sql = self.sql_alter_column % {
  721. "table": self.quote_name(model._meta.db_table),
  722. "changes": changes_sql,
  723. }
  724. self.execute(sql, params)
  725. # Reset connection if required
  726. if self.connection.features.connection_persists_old_columns:
  727. self.connection.close()
  728. def _alter_column_null_sql(self, model, old_field, new_field):
  729. """
  730. Hook to specialize column null alteration.
  731. Return a (sql, params) fragment to set a column to null or non-null
  732. as required by new_field, or None if no changes are required.
  733. """
  734. if (self.connection.features.interprets_empty_strings_as_nulls and
  735. new_field.get_internal_type() in ("CharField", "TextField")):
  736. # The field is nullable in the database anyway, leave it alone.
  737. return
  738. else:
  739. new_db_params = new_field.db_parameters(connection=self.connection)
  740. sql = self.sql_alter_column_null if new_field.null else self.sql_alter_column_not_null
  741. return (
  742. sql % {
  743. 'column': self.quote_name(new_field.column),
  744. 'type': new_db_params['type'],
  745. },
  746. [],
  747. )
  748. def _alter_column_default_sql(self, model, old_field, new_field, drop=False):
  749. """
  750. Hook to specialize column default alteration.
  751. Return a (sql, params) fragment to add or drop (depending on the drop
  752. argument) a default to new_field's column.
  753. """
  754. new_default = self.effective_default(new_field)
  755. default = '%s'
  756. params = [new_default]
  757. if drop:
  758. params = []
  759. elif self.connection.features.requires_literal_defaults:
  760. # Some databases (Oracle) can't take defaults as a parameter
  761. # If this is the case, the SchemaEditor for that database should
  762. # implement prepare_default().
  763. default = self.prepare_default(new_default)
  764. params = []
  765. new_db_params = new_field.db_parameters(connection=self.connection)
  766. sql = self.sql_alter_column_no_default if drop else self.sql_alter_column_default
  767. return (
  768. sql % {
  769. 'column': self.quote_name(new_field.column),
  770. 'type': new_db_params['type'],
  771. 'default': default,
  772. },
  773. params,
  774. )
  775. def _alter_column_type_sql(self, model, old_field, new_field, new_type):
  776. """
  777. Hook to specialize column type alteration for different backends,
  778. for cases when a creation type is different to an alteration type
  779. (e.g. SERIAL in PostgreSQL, PostGIS fields).
  780. Return a two-tuple of: an SQL fragment of (sql, params) to insert into
  781. an ALTER TABLE statement and a list of extra (sql, params) tuples to
  782. run once the field is altered.
  783. """
  784. return (
  785. (
  786. self.sql_alter_column_type % {
  787. "column": self.quote_name(new_field.column),
  788. "type": new_type,
  789. },
  790. [],
  791. ),
  792. [],
  793. )
  794. def _alter_many_to_many(self, model, old_field, new_field, strict):
  795. """Alter M2Ms to repoint their to= endpoints."""
  796. # Rename the through table
  797. if old_field.remote_field.through._meta.db_table != new_field.remote_field.through._meta.db_table:
  798. self.alter_db_table(old_field.remote_field.through, old_field.remote_field.through._meta.db_table,
  799. new_field.remote_field.through._meta.db_table)
  800. # Repoint the FK to the other side
  801. self.alter_field(
  802. new_field.remote_field.through,
  803. # We need the field that points to the target model, so we can tell alter_field to change it -
  804. # this is m2m_reverse_field_name() (as opposed to m2m_field_name, which points to our model)
  805. old_field.remote_field.through._meta.get_field(old_field.m2m_reverse_field_name()),
  806. new_field.remote_field.through._meta.get_field(new_field.m2m_reverse_field_name()),
  807. )
  808. self.alter_field(
  809. new_field.remote_field.through,
  810. # for self-referential models we need to alter field from the other end too
  811. old_field.remote_field.through._meta.get_field(old_field.m2m_field_name()),
  812. new_field.remote_field.through._meta.get_field(new_field.m2m_field_name()),
  813. )
  814. def _create_index_name(self, table_name, column_names, suffix=""):
  815. """
  816. Generate a unique name for an index/unique constraint.
  817. The name is divided into 3 parts: the table name, the column names,
  818. and a unique digest and suffix.
  819. """
  820. _, table_name = split_identifier(table_name)
  821. hash_suffix_part = '%s%s' % (names_digest(table_name, *column_names, length=8), suffix)
  822. max_length = self.connection.ops.max_name_length() or 200
  823. # If everything fits into max_length, use that name.
  824. index_name = '%s_%s_%s' % (table_name, '_'.join(column_names), hash_suffix_part)
  825. if len(index_name) <= max_length:
  826. return index_name
  827. # Shorten a long suffix.
  828. if len(hash_suffix_part) > max_length / 3:
  829. hash_suffix_part = hash_suffix_part[:max_length // 3]
  830. other_length = (max_length - len(hash_suffix_part)) // 2 - 1
  831. index_name = '%s_%s_%s' % (
  832. table_name[:other_length],
  833. '_'.join(column_names)[:other_length],
  834. hash_suffix_part,
  835. )
  836. # Prepend D if needed to prevent the name from starting with an
  837. # underscore or a number (not permitted on Oracle).
  838. if index_name[0] == "_" or index_name[0].isdigit():
  839. index_name = "D%s" % index_name[:-1]
  840. return index_name
  841. def _get_index_tablespace_sql(self, model, fields, db_tablespace=None):
  842. if db_tablespace is None:
  843. if len(fields) == 1 and fields[0].db_tablespace:
  844. db_tablespace = fields[0].db_tablespace
  845. elif model._meta.db_tablespace:
  846. db_tablespace = model._meta.db_tablespace
  847. if db_tablespace is not None:
  848. return ' ' + self.connection.ops.tablespace_sql(db_tablespace)
  849. return ''
  850. def _create_index_sql(self, model, fields, *, name=None, suffix='', using='',
  851. db_tablespace=None, col_suffixes=(), sql=None, opclasses=(),
  852. condition=None):
  853. """
  854. Return the SQL statement to create the index for one or several fields.
  855. `sql` can be specified if the syntax differs from the standard (GIS
  856. indexes, ...).
  857. """
  858. tablespace_sql = self._get_index_tablespace_sql(model, fields, db_tablespace=db_tablespace)
  859. columns = [field.column for field in fields]
  860. sql_create_index = sql or self.sql_create_index
  861. table = model._meta.db_table
  862. def create_index_name(*args, **kwargs):
  863. nonlocal name
  864. if name is None:
  865. name = self._create_index_name(*args, **kwargs)
  866. return self.quote_name(name)
  867. return Statement(
  868. sql_create_index,
  869. table=Table(table, self.quote_name),
  870. name=IndexName(table, columns, suffix, create_index_name),
  871. using=using,
  872. columns=self._index_columns(table, columns, col_suffixes, opclasses),
  873. extra=tablespace_sql,
  874. condition=(' WHERE ' + condition) if condition else '',
  875. )
  876. def _delete_index_sql(self, model, name):
  877. return Statement(
  878. self.sql_delete_index,
  879. table=Table(model._meta.db_table, self.quote_name),
  880. name=self.quote_name(name),
  881. )
  882. def _index_columns(self, table, columns, col_suffixes, opclasses):
  883. return Columns(table, columns, self.quote_name, col_suffixes=col_suffixes)
  884. def _model_indexes_sql(self, model):
  885. """
  886. Return a list of all index SQL statements (field indexes,
  887. index_together, Meta.indexes) for the specified model.
  888. """
  889. if not model._meta.managed or model._meta.proxy or model._meta.swapped:
  890. return []
  891. output = []
  892. for field in model._meta.local_fields:
  893. output.extend(self._field_indexes_sql(model, field))
  894. for field_names in model._meta.index_together:
  895. fields = [model._meta.get_field(field) for field in field_names]
  896. output.append(self._create_index_sql(model, fields, suffix="_idx"))
  897. for index in model._meta.indexes:
  898. output.append(index.create_sql(model, self))
  899. return output
  900. def _field_indexes_sql(self, model, field):
  901. """
  902. Return a list of all index SQL statements for the specified field.
  903. """
  904. output = []
  905. if self._field_should_be_indexed(model, field):
  906. output.append(self._create_index_sql(model, [field]))
  907. return output
  908. def _field_should_be_indexed(self, model, field):
  909. return field.db_index and not field.unique
  910. def _field_became_primary_key(self, old_field, new_field):
  911. return not old_field.primary_key and new_field.primary_key
  912. def _unique_should_be_added(self, old_field, new_field):
  913. return (not old_field.unique and new_field.unique) or (
  914. old_field.primary_key and not new_field.primary_key and new_field.unique
  915. )
  916. def _rename_field_sql(self, table, old_field, new_field, new_type):
  917. return self.sql_rename_column % {
  918. "table": self.quote_name(table),
  919. "old_column": self.quote_name(old_field.column),
  920. "new_column": self.quote_name(new_field.column),
  921. "type": new_type,
  922. }
  923. def _create_fk_sql(self, model, field, suffix):
  924. def create_fk_name(*args, **kwargs):
  925. return self.quote_name(self._create_index_name(*args, **kwargs))
  926. table = Table(model._meta.db_table, self.quote_name)
  927. name = ForeignKeyName(
  928. model._meta.db_table,
  929. [field.column],
  930. split_identifier(field.target_field.model._meta.db_table)[1],
  931. [field.target_field.column],
  932. suffix,
  933. create_fk_name,
  934. )
  935. column = Columns(model._meta.db_table, [field.column], self.quote_name)
  936. to_table = Table(field.target_field.model._meta.db_table, self.quote_name)
  937. to_column = Columns(field.target_field.model._meta.db_table, [field.target_field.column], self.quote_name)
  938. deferrable = self.connection.ops.deferrable_sql()
  939. return Statement(
  940. self.sql_create_fk,
  941. table=table,
  942. name=name,
  943. column=column,
  944. to_table=to_table,
  945. to_column=to_column,
  946. deferrable=deferrable,
  947. )
  948. def _delete_fk_sql(self, model, name):
  949. return self._delete_constraint_sql(self.sql_delete_fk, model, name)
  950. def _unique_sql(self, model, fields, name, condition=None):
  951. if condition:
  952. # Databases support conditional unique constraints via a unique
  953. # index.
  954. sql = self._create_unique_sql(model, fields, name=name, condition=condition)
  955. if sql:
  956. self.deferred_sql.append(sql)
  957. return None
  958. constraint = self.sql_unique_constraint % {
  959. 'columns': ', '.join(map(self.quote_name, fields)),
  960. }
  961. return self.sql_constraint % {
  962. 'name': self.quote_name(name),
  963. 'constraint': constraint,
  964. }
  965. def _create_unique_sql(self, model, columns, name=None, condition=None):
  966. def create_unique_name(*args, **kwargs):
  967. return self.quote_name(self._create_index_name(*args, **kwargs))
  968. table = Table(model._meta.db_table, self.quote_name)
  969. if name is None:
  970. name = IndexName(model._meta.db_table, columns, '_uniq', create_unique_name)
  971. else:
  972. name = self.quote_name(name)
  973. columns = Columns(table, columns, self.quote_name)
  974. if condition:
  975. return Statement(
  976. self.sql_create_unique_index,
  977. table=table,
  978. name=name,
  979. columns=columns,
  980. condition=' WHERE ' + condition,
  981. ) if self.connection.features.supports_partial_indexes else None
  982. else:
  983. return Statement(
  984. self.sql_create_unique,
  985. table=table,
  986. name=name,
  987. columns=columns,
  988. )
  989. def _delete_unique_sql(self, model, name, condition=None):
  990. if condition:
  991. return (
  992. self._delete_constraint_sql(self.sql_delete_index, model, name)
  993. if self.connection.features.supports_partial_indexes else None
  994. )
  995. return self._delete_constraint_sql(self.sql_delete_unique, model, name)
  996. def _check_sql(self, name, check):
  997. return self.sql_constraint % {
  998. 'name': self.quote_name(name),
  999. 'constraint': self.sql_check_constraint % {'check': check},
  1000. }
  1001. def _create_check_sql(self, model, name, check):
  1002. return Statement(
  1003. self.sql_create_check,
  1004. table=Table(model._meta.db_table, self.quote_name),
  1005. name=self.quote_name(name),
  1006. check=check,
  1007. )
  1008. def _delete_check_sql(self, model, name):
  1009. return self._delete_constraint_sql(self.sql_delete_check, model, name)
  1010. def _delete_constraint_sql(self, template, model, name):
  1011. return Statement(
  1012. template,
  1013. table=Table(model._meta.db_table, self.quote_name),
  1014. name=self.quote_name(name),
  1015. )
  1016. def _constraint_names(self, model, column_names=None, unique=None,
  1017. primary_key=None, index=None, foreign_key=None,
  1018. check=None, type_=None, exclude=None):
  1019. """Return all constraint names matching the columns and conditions."""
  1020. if column_names is not None:
  1021. column_names = [
  1022. self.connection.introspection.identifier_converter(name)
  1023. for name in column_names
  1024. ]
  1025. with self.connection.cursor() as cursor:
  1026. constraints = self.connection.introspection.get_constraints(cursor, model._meta.db_table)
  1027. result = []
  1028. for name, infodict in constraints.items():
  1029. if column_names is None or column_names == infodict['columns']:
  1030. if unique is not None and infodict['unique'] != unique:
  1031. continue
  1032. if primary_key is not None and infodict['primary_key'] != primary_key:
  1033. continue
  1034. if index is not None and infodict['index'] != index:
  1035. continue
  1036. if check is not None and infodict['check'] != check:
  1037. continue
  1038. if foreign_key is not None and not infodict['foreign_key']:
  1039. continue
  1040. if type_ is not None and infodict['type'] != type_:
  1041. continue
  1042. if not exclude or name not in exclude:
  1043. result.append(name)
  1044. return result
  1045. def _delete_primary_key(self, model, strict=False):
  1046. constraint_names = self._constraint_names(model, primary_key=True)
  1047. if strict and len(constraint_names) != 1:
  1048. raise ValueError('Found wrong number (%s) of PK constraints for %s' % (
  1049. len(constraint_names),
  1050. model._meta.db_table,
  1051. ))
  1052. for constraint_name in constraint_names:
  1053. self.execute(self._delete_primary_key_sql(model, constraint_name))
  1054. def _create_primary_key_sql(self, model, field):
  1055. return Statement(
  1056. self.sql_create_pk,
  1057. table=Table(model._meta.db_table, self.quote_name),
  1058. name=self.quote_name(
  1059. self._create_index_name(model._meta.db_table, [field.column], suffix="_pk")
  1060. ),
  1061. columns=Columns(model._meta.db_table, [field.column], self.quote_name),
  1062. )
  1063. def _delete_primary_key_sql(self, model, name):
  1064. return self._delete_constraint_sql(self.sql_delete_pk, model, name)
  1065. def remove_procedure(self, procedure_name, param_types=()):
  1066. sql = self.sql_delete_procedure % {
  1067. 'procedure': self.quote_name(procedure_name),
  1068. 'param_types': ','.join(param_types),
  1069. }
  1070. self.execute(sql)