toimpl.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
  2. # mypy: no-warn-return-any, allow-any-generics
  3. from typing import TYPE_CHECKING
  4. from sqlalchemy import schema as sa_schema
  5. from . import ops
  6. from .base import Operations
  7. from ..util.sqla_compat import _copy
  8. from ..util.sqla_compat import sqla_14
  9. if TYPE_CHECKING:
  10. from sqlalchemy.sql.schema import Table
  11. @Operations.implementation_for(ops.AlterColumnOp)
  12. def alter_column(
  13. operations: "Operations", operation: "ops.AlterColumnOp"
  14. ) -> None:
  15. compiler = operations.impl.dialect.statement_compiler(
  16. operations.impl.dialect, None
  17. )
  18. existing_type = operation.existing_type
  19. existing_nullable = operation.existing_nullable
  20. existing_server_default = operation.existing_server_default
  21. type_ = operation.modify_type
  22. column_name = operation.column_name
  23. table_name = operation.table_name
  24. schema = operation.schema
  25. server_default = operation.modify_server_default
  26. new_column_name = operation.modify_name
  27. nullable = operation.modify_nullable
  28. comment = operation.modify_comment
  29. existing_comment = operation.existing_comment
  30. def _count_constraint(constraint):
  31. return not isinstance(constraint, sa_schema.PrimaryKeyConstraint) and (
  32. not constraint._create_rule or constraint._create_rule(compiler)
  33. )
  34. if existing_type and type_:
  35. t = operations.schema_obj.table(
  36. table_name,
  37. sa_schema.Column(column_name, existing_type),
  38. schema=schema,
  39. )
  40. for constraint in t.constraints:
  41. if _count_constraint(constraint):
  42. operations.impl.drop_constraint(constraint)
  43. operations.impl.alter_column(
  44. table_name,
  45. column_name,
  46. nullable=nullable,
  47. server_default=server_default,
  48. name=new_column_name,
  49. type_=type_,
  50. schema=schema,
  51. existing_type=existing_type,
  52. existing_server_default=existing_server_default,
  53. existing_nullable=existing_nullable,
  54. comment=comment,
  55. existing_comment=existing_comment,
  56. **operation.kw,
  57. )
  58. if type_:
  59. t = operations.schema_obj.table(
  60. table_name,
  61. operations.schema_obj.column(column_name, type_),
  62. schema=schema,
  63. )
  64. for constraint in t.constraints:
  65. if _count_constraint(constraint):
  66. operations.impl.add_constraint(constraint)
  67. @Operations.implementation_for(ops.DropTableOp)
  68. def drop_table(operations: "Operations", operation: "ops.DropTableOp") -> None:
  69. operations.impl.drop_table(
  70. operation.to_table(operations.migration_context)
  71. )
  72. @Operations.implementation_for(ops.DropColumnOp)
  73. def drop_column(
  74. operations: "Operations", operation: "ops.DropColumnOp"
  75. ) -> None:
  76. column = operation.to_column(operations.migration_context)
  77. operations.impl.drop_column(
  78. operation.table_name, column, schema=operation.schema, **operation.kw
  79. )
  80. @Operations.implementation_for(ops.CreateIndexOp)
  81. def create_index(
  82. operations: "Operations", operation: "ops.CreateIndexOp"
  83. ) -> None:
  84. idx = operation.to_index(operations.migration_context)
  85. kw = {}
  86. if operation.if_not_exists is not None:
  87. if not sqla_14:
  88. raise NotImplementedError("SQLAlchemy 1.4+ required")
  89. kw["if_not_exists"] = operation.if_not_exists
  90. operations.impl.create_index(idx, **kw)
  91. @Operations.implementation_for(ops.DropIndexOp)
  92. def drop_index(operations: "Operations", operation: "ops.DropIndexOp") -> None:
  93. kw = {}
  94. if operation.if_exists is not None:
  95. if not sqla_14:
  96. raise NotImplementedError("SQLAlchemy 1.4+ required")
  97. kw["if_exists"] = operation.if_exists
  98. operations.impl.drop_index(
  99. operation.to_index(operations.migration_context),
  100. **kw,
  101. )
  102. @Operations.implementation_for(ops.CreateTableOp)
  103. def create_table(
  104. operations: "Operations", operation: "ops.CreateTableOp"
  105. ) -> "Table":
  106. table = operation.to_table(operations.migration_context)
  107. operations.impl.create_table(table)
  108. return table
  109. @Operations.implementation_for(ops.RenameTableOp)
  110. def rename_table(
  111. operations: "Operations", operation: "ops.RenameTableOp"
  112. ) -> None:
  113. operations.impl.rename_table(
  114. operation.table_name, operation.new_table_name, schema=operation.schema
  115. )
  116. @Operations.implementation_for(ops.CreateTableCommentOp)
  117. def create_table_comment(
  118. operations: "Operations", operation: "ops.CreateTableCommentOp"
  119. ) -> None:
  120. table = operation.to_table(operations.migration_context)
  121. operations.impl.create_table_comment(table)
  122. @Operations.implementation_for(ops.DropTableCommentOp)
  123. def drop_table_comment(
  124. operations: "Operations", operation: "ops.DropTableCommentOp"
  125. ) -> None:
  126. table = operation.to_table(operations.migration_context)
  127. operations.impl.drop_table_comment(table)
  128. @Operations.implementation_for(ops.AddColumnOp)
  129. def add_column(operations: "Operations", operation: "ops.AddColumnOp") -> None:
  130. table_name = operation.table_name
  131. column = operation.column
  132. schema = operation.schema
  133. kw = operation.kw
  134. if column.table is not None:
  135. column = _copy(column)
  136. t = operations.schema_obj.table(table_name, column, schema=schema)
  137. operations.impl.add_column(table_name, column, schema=schema, **kw)
  138. for constraint in t.constraints:
  139. if not isinstance(constraint, sa_schema.PrimaryKeyConstraint):
  140. operations.impl.add_constraint(constraint)
  141. for index in t.indexes:
  142. operations.impl.create_index(index)
  143. with_comment = (
  144. operations.impl.dialect.supports_comments
  145. and not operations.impl.dialect.inline_comments
  146. )
  147. comment = column.comment
  148. if comment and with_comment:
  149. operations.impl.create_column_comment(column)
  150. @Operations.implementation_for(ops.AddConstraintOp)
  151. def create_constraint(
  152. operations: "Operations", operation: "ops.AddConstraintOp"
  153. ) -> None:
  154. operations.impl.add_constraint(
  155. operation.to_constraint(operations.migration_context)
  156. )
  157. @Operations.implementation_for(ops.DropConstraintOp)
  158. def drop_constraint(
  159. operations: "Operations", operation: "ops.DropConstraintOp"
  160. ) -> None:
  161. operations.impl.drop_constraint(
  162. operations.schema_obj.generic_constraint(
  163. operation.constraint_name,
  164. operation.table_name,
  165. operation.constraint_type,
  166. schema=operation.schema,
  167. )
  168. )
  169. @Operations.implementation_for(ops.BulkInsertOp)
  170. def bulk_insert(
  171. operations: "Operations", operation: "ops.BulkInsertOp"
  172. ) -> None:
  173. operations.impl.bulk_insert( # type: ignore[union-attr]
  174. operation.table, operation.rows, multiinsert=operation.multiinsert
  175. )
  176. @Operations.implementation_for(ops.ExecuteSQLOp)
  177. def execute_sql(
  178. operations: "Operations", operation: "ops.ExecuteSQLOp"
  179. ) -> None:
  180. operations.migration_context.impl.execute(
  181. operation.sqltext, execution_options=operation.execution_options
  182. )