alembic 1.13.0__py3-none-any.whl → 1.13.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. alembic/__init__.py +1 -1
  2. alembic/autogenerate/__init__.py +10 -10
  3. alembic/autogenerate/api.py +9 -7
  4. alembic/autogenerate/compare.py +6 -5
  5. alembic/autogenerate/render.py +34 -24
  6. alembic/autogenerate/rewriter.py +26 -13
  7. alembic/command.py +27 -16
  8. alembic/config.py +25 -19
  9. alembic/context.pyi +10 -5
  10. alembic/ddl/__init__.py +1 -1
  11. alembic/ddl/_autogen.py +19 -13
  12. alembic/ddl/base.py +17 -13
  13. alembic/ddl/impl.py +27 -19
  14. alembic/ddl/mssql.py +4 -1
  15. alembic/ddl/mysql.py +54 -34
  16. alembic/ddl/oracle.py +9 -4
  17. alembic/ddl/postgresql.py +18 -10
  18. alembic/ddl/sqlite.py +8 -6
  19. alembic/op.pyi +46 -8
  20. alembic/operations/base.py +69 -16
  21. alembic/operations/batch.py +7 -8
  22. alembic/operations/ops.py +57 -35
  23. alembic/operations/schemaobj.py +11 -8
  24. alembic/operations/toimpl.py +3 -0
  25. alembic/runtime/environment.py +20 -13
  26. alembic/runtime/migration.py +34 -18
  27. alembic/script/base.py +24 -24
  28. alembic/script/revision.py +53 -33
  29. alembic/script/write_hooks.py +3 -0
  30. alembic/templates/async/alembic.ini.mako +3 -3
  31. alembic/templates/generic/alembic.ini.mako +2 -2
  32. alembic/templates/multidb/alembic.ini.mako +2 -2
  33. alembic/testing/fixtures.py +20 -8
  34. alembic/testing/suite/test_autogen_computed.py +1 -0
  35. alembic/testing/suite/test_environment.py +3 -3
  36. alembic/util/__init__.py +31 -31
  37. alembic/util/compat.py +25 -8
  38. alembic/util/langhelpers.py +78 -36
  39. alembic/util/messaging.py +15 -6
  40. alembic/util/pyfiles.py +7 -3
  41. alembic/util/sqla_compat.py +41 -14
  42. {alembic-1.13.0.dist-info → alembic-1.13.2.dist-info}/LICENSE +2 -2
  43. {alembic-1.13.0.dist-info → alembic-1.13.2.dist-info}/METADATA +1 -1
  44. alembic-1.13.2.dist-info/RECORD +83 -0
  45. {alembic-1.13.0.dist-info → alembic-1.13.2.dist-info}/WHEEL +1 -1
  46. alembic-1.13.0.dist-info/RECORD +0 -83
  47. {alembic-1.13.0.dist-info → alembic-1.13.2.dist-info}/entry_points.txt +0 -0
  48. {alembic-1.13.0.dist-info → alembic-1.13.2.dist-info}/top_level.txt +0 -0
alembic/ddl/_autogen.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  from typing import Any
@@ -19,7 +22,6 @@ from sqlalchemy.sql.schema import Index
19
22
  from sqlalchemy.sql.schema import UniqueConstraint
20
23
  from typing_extensions import TypeGuard
21
24
 
22
- from alembic.ddl.base import _fk_spec
23
25
  from .. import util
24
26
  from ..util import sqla_compat
25
27
 
@@ -275,7 +277,7 @@ class _fk_constraint_sig(_constraint_sig[ForeignKeyConstraint]):
275
277
  ondelete,
276
278
  deferrable,
277
279
  initially,
278
- ) = _fk_spec(const)
280
+ ) = sqla_compat._fk_spec(const)
279
281
 
280
282
  self._sig: Tuple[Any, ...] = (
281
283
  self.source_schema,
@@ -285,18 +287,22 @@ class _fk_constraint_sig(_constraint_sig[ForeignKeyConstraint]):
285
287
  self.target_table,
286
288
  tuple(self.target_columns),
287
289
  ) + (
288
- (None if onupdate.lower() == "no action" else onupdate.lower())
289
- if onupdate
290
- else None,
291
- (None if ondelete.lower() == "no action" else ondelete.lower())
292
- if ondelete
293
- else None,
290
+ (
291
+ (None if onupdate.lower() == "no action" else onupdate.lower())
292
+ if onupdate
293
+ else None
294
+ ),
295
+ (
296
+ (None if ondelete.lower() == "no action" else ondelete.lower())
297
+ if ondelete
298
+ else None
299
+ ),
294
300
  # convert initially + deferrable into one three-state value
295
- "initially_deferrable"
296
- if initially and initially.lower() == "deferred"
297
- else "deferrable"
298
- if deferrable
299
- else "not deferrable",
301
+ (
302
+ "initially_deferrable"
303
+ if initially and initially.lower() == "deferred"
304
+ else "deferrable" if deferrable else "not deferrable"
305
+ ),
300
306
  )
301
307
 
302
308
  @util.memoized_property
alembic/ddl/base.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  import functools
@@ -37,7 +40,6 @@ _ServerDefault = Union["TextClause", "FetchedValue", "Function[Any]", str]
37
40
 
38
41
 
39
42
  class AlterTable(DDLElement):
40
-
41
43
  """Represent an ALTER TABLE statement.
42
44
 
43
45
  Only the string name and optional schema name of the table
@@ -173,7 +175,7 @@ class ColumnComment(AlterColumn):
173
175
  self.comment = comment
174
176
 
175
177
 
176
- @compiles(RenameTable)
178
+ @compiles(RenameTable) # type: ignore[misc]
177
179
  def visit_rename_table(
178
180
  element: RenameTable, compiler: DDLCompiler, **kw
179
181
  ) -> str:
@@ -183,7 +185,7 @@ def visit_rename_table(
183
185
  )
184
186
 
185
187
 
186
- @compiles(AddColumn)
188
+ @compiles(AddColumn) # type: ignore[misc]
187
189
  def visit_add_column(element: AddColumn, compiler: DDLCompiler, **kw) -> str:
188
190
  return "%s %s" % (
189
191
  alter_table(compiler, element.table_name, element.schema),
@@ -191,7 +193,7 @@ def visit_add_column(element: AddColumn, compiler: DDLCompiler, **kw) -> str:
191
193
  )
192
194
 
193
195
 
194
- @compiles(DropColumn)
196
+ @compiles(DropColumn) # type: ignore[misc]
195
197
  def visit_drop_column(element: DropColumn, compiler: DDLCompiler, **kw) -> str:
196
198
  return "%s %s" % (
197
199
  alter_table(compiler, element.table_name, element.schema),
@@ -199,7 +201,7 @@ def visit_drop_column(element: DropColumn, compiler: DDLCompiler, **kw) -> str:
199
201
  )
200
202
 
201
203
 
202
- @compiles(ColumnNullable)
204
+ @compiles(ColumnNullable) # type: ignore[misc]
203
205
  def visit_column_nullable(
204
206
  element: ColumnNullable, compiler: DDLCompiler, **kw
205
207
  ) -> str:
@@ -210,7 +212,7 @@ def visit_column_nullable(
210
212
  )
211
213
 
212
214
 
213
- @compiles(ColumnType)
215
+ @compiles(ColumnType) # type: ignore[misc]
214
216
  def visit_column_type(element: ColumnType, compiler: DDLCompiler, **kw) -> str:
215
217
  return "%s %s %s" % (
216
218
  alter_table(compiler, element.table_name, element.schema),
@@ -219,7 +221,7 @@ def visit_column_type(element: ColumnType, compiler: DDLCompiler, **kw) -> str:
219
221
  )
220
222
 
221
223
 
222
- @compiles(ColumnName)
224
+ @compiles(ColumnName) # type: ignore[misc]
223
225
  def visit_column_name(element: ColumnName, compiler: DDLCompiler, **kw) -> str:
224
226
  return "%s RENAME %s TO %s" % (
225
227
  alter_table(compiler, element.table_name, element.schema),
@@ -228,20 +230,22 @@ def visit_column_name(element: ColumnName, compiler: DDLCompiler, **kw) -> str:
228
230
  )
229
231
 
230
232
 
231
- @compiles(ColumnDefault)
233
+ @compiles(ColumnDefault) # type: ignore[misc]
232
234
  def visit_column_default(
233
235
  element: ColumnDefault, compiler: DDLCompiler, **kw
234
236
  ) -> str:
235
237
  return "%s %s %s" % (
236
238
  alter_table(compiler, element.table_name, element.schema),
237
239
  alter_column(compiler, element.column_name),
238
- "SET DEFAULT %s" % format_server_default(compiler, element.default)
239
- if element.default is not None
240
- else "DROP DEFAULT",
240
+ (
241
+ "SET DEFAULT %s" % format_server_default(compiler, element.default)
242
+ if element.default is not None
243
+ else "DROP DEFAULT"
244
+ ),
241
245
  )
242
246
 
243
247
 
244
- @compiles(ComputedColumnDefault)
248
+ @compiles(ComputedColumnDefault) # type: ignore[misc]
245
249
  def visit_computed_column(
246
250
  element: ComputedColumnDefault, compiler: DDLCompiler, **kw
247
251
  ):
@@ -251,7 +255,7 @@ def visit_computed_column(
251
255
  )
252
256
 
253
257
 
254
- @compiles(IdentityColumnDefault)
258
+ @compiles(IdentityColumnDefault) # type: ignore[misc]
255
259
  def visit_identity_column(
256
260
  element: IdentityColumnDefault, compiler: DDLCompiler, **kw
257
261
  ):
alembic/ddl/impl.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  import logging
@@ -23,8 +26,8 @@ from sqlalchemy import text
23
26
 
24
27
  from . import _autogen
25
28
  from . import base
26
- from ._autogen import _constraint_sig
27
- from ._autogen import ComparisonResult
29
+ from ._autogen import _constraint_sig as _constraint_sig
30
+ from ._autogen import ComparisonResult as ComparisonResult
28
31
  from .. import util
29
32
  from ..util import sqla_compat
30
33
 
@@ -74,7 +77,6 @@ _impls: Dict[str, Type[DefaultImpl]] = {}
74
77
 
75
78
 
76
79
  class DefaultImpl(metaclass=ImplMeta):
77
-
78
80
  """Provide the entrypoint for major migration operations,
79
81
  including database-specific behavioral variances.
80
82
 
@@ -165,16 +167,15 @@ class DefaultImpl(metaclass=ImplMeta):
165
167
  def _exec(
166
168
  self,
167
169
  construct: Union[Executable, str],
168
- execution_options: Optional[dict[str, Any]] = None,
169
- multiparams: Sequence[dict] = (),
170
- params: Dict[str, Any] = util.immutabledict(),
170
+ execution_options: Optional[Mapping[str, Any]] = None,
171
+ multiparams: Optional[Sequence[Mapping[str, Any]]] = None,
172
+ params: Mapping[str, Any] = util.immutabledict(),
171
173
  ) -> Optional[CursorResult]:
172
174
  if isinstance(construct, str):
173
175
  construct = text(construct)
174
176
  if self.as_sql:
175
- if multiparams or params:
176
- # TODO: coverage
177
- raise Exception("Execution arguments not allowed with as_sql")
177
+ if multiparams is not None or params:
178
+ raise TypeError("SQL parameters not allowed with as_sql")
178
179
 
179
180
  compile_kw: dict[str, Any]
180
181
  if self.literal_binds and not isinstance(
@@ -197,11 +198,16 @@ class DefaultImpl(metaclass=ImplMeta):
197
198
  assert conn is not None
198
199
  if execution_options:
199
200
  conn = conn.execution_options(**execution_options)
200
- if params:
201
- assert isinstance(multiparams, tuple)
202
- multiparams += (params,)
203
201
 
204
- return conn.execute(construct, multiparams)
202
+ if params and multiparams is not None:
203
+ raise TypeError(
204
+ "Can't send params and multiparams at the same time"
205
+ )
206
+
207
+ if multiparams:
208
+ return conn.execute(construct, multiparams)
209
+ else:
210
+ return conn.execute(construct, params)
205
211
 
206
212
  def execute(
207
213
  self,
@@ -418,13 +424,15 @@ class DefaultImpl(metaclass=ImplMeta):
418
424
  self._exec(
419
425
  sqla_compat._insert_inline(table).values(
420
426
  **{
421
- k: sqla_compat._literal_bindparam(
422
- k, v, type_=table.c[k].type
423
- )
424
- if not isinstance(
425
- v, sqla_compat._literal_bindparam
427
+ k: (
428
+ sqla_compat._literal_bindparam(
429
+ k, v, type_=table.c[k].type
430
+ )
431
+ if not isinstance(
432
+ v, sqla_compat._literal_bindparam
433
+ )
434
+ else v
426
435
  )
427
- else v
428
436
  for k, v in row.items()
429
437
  }
430
438
  )
alembic/ddl/mssql.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  import re
@@ -9,7 +12,6 @@ from typing import TYPE_CHECKING
9
12
  from typing import Union
10
13
 
11
14
  from sqlalchemy import types as sqltypes
12
- from sqlalchemy.ext.compiler import compiles
13
15
  from sqlalchemy.schema import Column
14
16
  from sqlalchemy.schema import CreateIndex
15
17
  from sqlalchemy.sql.base import Executable
@@ -30,6 +32,7 @@ from .base import RenameTable
30
32
  from .impl import DefaultImpl
31
33
  from .. import util
32
34
  from ..util import sqla_compat
35
+ from ..util.sqla_compat import compiles
33
36
 
34
37
  if TYPE_CHECKING:
35
38
  from typing import Literal
alembic/ddl/mysql.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  import re
@@ -8,7 +11,6 @@ from typing import Union
8
11
 
9
12
  from sqlalchemy import schema
10
13
  from sqlalchemy import types as sqltypes
11
- from sqlalchemy.ext.compiler import compiles
12
14
 
13
15
  from .base import alter_table
14
16
  from .base import AlterColumn
@@ -23,6 +25,7 @@ from .. import util
23
25
  from ..util import sqla_compat
24
26
  from ..util.sqla_compat import _is_mariadb
25
27
  from ..util.sqla_compat import _is_type_bound
28
+ from ..util.sqla_compat import compiles
26
29
 
27
30
  if TYPE_CHECKING:
28
31
  from typing import Literal
@@ -91,21 +94,29 @@ class MySQLImpl(DefaultImpl):
91
94
  column_name,
92
95
  schema=schema,
93
96
  newname=name if name is not None else column_name,
94
- nullable=nullable
95
- if nullable is not None
96
- else existing_nullable
97
- if existing_nullable is not None
98
- else True,
97
+ nullable=(
98
+ nullable
99
+ if nullable is not None
100
+ else (
101
+ existing_nullable
102
+ if existing_nullable is not None
103
+ else True
104
+ )
105
+ ),
99
106
  type_=type_ if type_ is not None else existing_type,
100
- default=server_default
101
- if server_default is not False
102
- else existing_server_default,
103
- autoincrement=autoincrement
104
- if autoincrement is not None
105
- else existing_autoincrement,
106
- comment=comment
107
- if comment is not False
108
- else existing_comment,
107
+ default=(
108
+ server_default
109
+ if server_default is not False
110
+ else existing_server_default
111
+ ),
112
+ autoincrement=(
113
+ autoincrement
114
+ if autoincrement is not None
115
+ else existing_autoincrement
116
+ ),
117
+ comment=(
118
+ comment if comment is not False else existing_comment
119
+ ),
109
120
  )
110
121
  )
111
122
  elif (
@@ -120,21 +131,29 @@ class MySQLImpl(DefaultImpl):
120
131
  column_name,
121
132
  schema=schema,
122
133
  newname=name if name is not None else column_name,
123
- nullable=nullable
124
- if nullable is not None
125
- else existing_nullable
126
- if existing_nullable is not None
127
- else True,
134
+ nullable=(
135
+ nullable
136
+ if nullable is not None
137
+ else (
138
+ existing_nullable
139
+ if existing_nullable is not None
140
+ else True
141
+ )
142
+ ),
128
143
  type_=type_ if type_ is not None else existing_type,
129
- default=server_default
130
- if server_default is not False
131
- else existing_server_default,
132
- autoincrement=autoincrement
133
- if autoincrement is not None
134
- else existing_autoincrement,
135
- comment=comment
136
- if comment is not False
137
- else existing_comment,
144
+ default=(
145
+ server_default
146
+ if server_default is not False
147
+ else existing_server_default
148
+ ),
149
+ autoincrement=(
150
+ autoincrement
151
+ if autoincrement is not None
152
+ else existing_autoincrement
153
+ ),
154
+ comment=(
155
+ comment if comment is not False else existing_comment
156
+ ),
138
157
  )
139
158
  )
140
159
  elif server_default is not False:
@@ -160,8 +179,7 @@ class MySQLImpl(DefaultImpl):
160
179
  ) -> bool:
161
180
  return (
162
181
  type_ is not None
163
- and type_._type_affinity # type:ignore[attr-defined]
164
- is sqltypes.DateTime
182
+ and type_._type_affinity is sqltypes.DateTime
165
183
  and server_default is not None
166
184
  )
167
185
 
@@ -366,9 +384,11 @@ def _mysql_alter_default(
366
384
  return "%s ALTER COLUMN %s %s" % (
367
385
  alter_table(compiler, element.table_name, element.schema),
368
386
  format_column_name(compiler, element.column_name),
369
- "SET DEFAULT %s" % format_server_default(compiler, element.default)
370
- if element.default is not None
371
- else "DROP DEFAULT",
387
+ (
388
+ "SET DEFAULT %s" % format_server_default(compiler, element.default)
389
+ if element.default is not None
390
+ else "DROP DEFAULT"
391
+ ),
372
392
  )
373
393
 
374
394
 
alembic/ddl/oracle.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  import re
@@ -5,7 +8,6 @@ from typing import Any
5
8
  from typing import Optional
6
9
  from typing import TYPE_CHECKING
7
10
 
8
- from sqlalchemy.ext.compiler import compiles
9
11
  from sqlalchemy.sql import sqltypes
10
12
 
11
13
  from .base import AddColumn
@@ -22,6 +24,7 @@ from .base import format_type
22
24
  from .base import IdentityColumnDefault
23
25
  from .base import RenameTable
24
26
  from .impl import DefaultImpl
27
+ from ..util.sqla_compat import compiles
25
28
 
26
29
  if TYPE_CHECKING:
27
30
  from sqlalchemy.dialects.oracle.base import OracleDDLCompiler
@@ -138,9 +141,11 @@ def visit_column_default(
138
141
  return "%s %s %s" % (
139
142
  alter_table(compiler, element.table_name, element.schema),
140
143
  alter_column(compiler, element.column_name),
141
- "DEFAULT %s" % format_server_default(compiler, element.default)
142
- if element.default is not None
143
- else "DEFAULT NULL",
144
+ (
145
+ "DEFAULT %s" % format_server_default(compiler, element.default)
146
+ if element.default is not None
147
+ else "DEFAULT NULL"
148
+ ),
144
149
  )
145
150
 
146
151
 
alembic/ddl/postgresql.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  import logging
@@ -30,7 +33,6 @@ from .base import alter_column
30
33
  from .base import alter_table
31
34
  from .base import AlterColumn
32
35
  from .base import ColumnComment
33
- from .base import compiles
34
36
  from .base import format_column_name
35
37
  from .base import format_table_name
36
38
  from .base import format_type
@@ -45,6 +47,7 @@ from ..operations import schemaobj
45
47
  from ..operations.base import BatchOperations
46
48
  from ..operations.base import Operations
47
49
  from ..util import sqla_compat
50
+ from ..util.sqla_compat import compiles
48
51
 
49
52
  if TYPE_CHECKING:
50
53
  from typing import Literal
@@ -136,7 +139,9 @@ class PostgresqlImpl(DefaultImpl):
136
139
  metadata_default = literal_column(metadata_default)
137
140
 
138
141
  # run a real compare against the server
139
- return not self.connection.scalar(
142
+ conn = self.connection
143
+ assert conn is not None
144
+ return not conn.scalar(
140
145
  sqla_compat._select(
141
146
  literal_column(conn_col_default) == metadata_default
142
147
  )
@@ -213,7 +218,8 @@ class PostgresqlImpl(DefaultImpl):
213
218
  "join pg_class t on t.oid=d.refobjid "
214
219
  "join pg_attribute a on a.attrelid=t.oid and "
215
220
  "a.attnum=d.refobjsubid "
216
- "where c.relkind='S' and c.relname=:seqname"
221
+ "where c.relkind='S' and "
222
+ "c.oid=cast(:seqname as regclass)"
217
223
  ),
218
224
  seqname=seq_match.group(1),
219
225
  ).first()
@@ -623,9 +629,8 @@ class CreateExcludeConstraintOp(ops.AddConstraintOp):
623
629
  return cls(
624
630
  constraint.name,
625
631
  constraint_table.name,
626
- [
627
- (expr, op)
628
- for expr, name, op in constraint._render_exprs # type:ignore[attr-defined] # noqa
632
+ [ # type: ignore
633
+ (expr, op) for expr, name, op in constraint._render_exprs
629
634
  ],
630
635
  where=cast("ColumnElement[bool] | None", constraint.where),
631
636
  schema=constraint_table.schema,
@@ -652,7 +657,7 @@ class CreateExcludeConstraintOp(ops.AddConstraintOp):
652
657
  expr,
653
658
  name,
654
659
  oper,
655
- ) in excl._render_exprs: # type:ignore[attr-defined]
660
+ ) in excl._render_exprs:
656
661
  t.append_column(Column(name, NULLTYPE))
657
662
  t.append_constraint(excl)
658
663
  return excl
@@ -710,7 +715,7 @@ class CreateExcludeConstraintOp(ops.AddConstraintOp):
710
715
  constraint_name: str,
711
716
  *elements: Any,
712
717
  **kw: Any,
713
- ):
718
+ ) -> Optional[Table]:
714
719
  """Issue a "create exclude constraint" instruction using the
715
720
  current batch migration context.
716
721
 
@@ -782,10 +787,13 @@ def _exclude_constraint(
782
787
  args = [
783
788
  "(%s, %r)"
784
789
  % (
785
- _render_potential_column(sqltext, autogen_context),
790
+ _render_potential_column(
791
+ sqltext, # type:ignore[arg-type]
792
+ autogen_context,
793
+ ),
786
794
  opstring,
787
795
  )
788
- for sqltext, name, opstring in constraint._render_exprs # type:ignore[attr-defined] # noqa
796
+ for sqltext, name, opstring in constraint._render_exprs
789
797
  ]
790
798
  if constraint.where is not None:
791
799
  args.append(
alembic/ddl/sqlite.py CHANGED
@@ -1,3 +1,6 @@
1
+ # mypy: allow-untyped-defs, allow-incomplete-defs, allow-untyped-calls
2
+ # mypy: no-warn-return-any, allow-any-generics
3
+
1
4
  from __future__ import annotations
2
5
 
3
6
  import re
@@ -11,13 +14,13 @@ from sqlalchemy import cast
11
14
  from sqlalchemy import JSON
12
15
  from sqlalchemy import schema
13
16
  from sqlalchemy import sql
14
- from sqlalchemy.ext.compiler import compiles
15
17
 
16
18
  from .base import alter_table
17
19
  from .base import format_table_name
18
20
  from .base import RenameTable
19
21
  from .impl import DefaultImpl
20
22
  from .. import util
23
+ from ..util.sqla_compat import compiles
21
24
 
22
25
  if TYPE_CHECKING:
23
26
  from sqlalchemy.engine.reflection import Inspector
@@ -71,13 +74,13 @@ class SQLiteImpl(DefaultImpl):
71
74
  def add_constraint(self, const: Constraint):
72
75
  # attempt to distinguish between an
73
76
  # auto-gen constraint and an explicit one
74
- if const._create_rule is None: # type:ignore[attr-defined]
77
+ if const._create_rule is None:
75
78
  raise NotImplementedError(
76
79
  "No support for ALTER of constraints in SQLite dialect. "
77
80
  "Please refer to the batch mode feature which allows for "
78
81
  "SQLite migrations using a copy-and-move strategy."
79
82
  )
80
- elif const._create_rule(self): # type:ignore[attr-defined]
83
+ elif const._create_rule(self):
81
84
  util.warn(
82
85
  "Skipping unsupported ALTER for "
83
86
  "creation of implicit constraint. "
@@ -86,7 +89,7 @@ class SQLiteImpl(DefaultImpl):
86
89
  )
87
90
 
88
91
  def drop_constraint(self, const: Constraint):
89
- if const._create_rule is None: # type:ignore[attr-defined]
92
+ if const._create_rule is None:
90
93
  raise NotImplementedError(
91
94
  "No support for ALTER of constraints in SQLite dialect. "
92
95
  "Please refer to the batch mode feature which allows for "
@@ -177,8 +180,7 @@ class SQLiteImpl(DefaultImpl):
177
180
  new_type: TypeEngine,
178
181
  ) -> None:
179
182
  if (
180
- existing.type._type_affinity # type:ignore[attr-defined]
181
- is not new_type._type_affinity # type:ignore[attr-defined]
183
+ existing.type._type_affinity is not new_type._type_affinity
182
184
  and not isinstance(new_type, JSON)
183
185
  ):
184
186
  existing_transfer["expr"] = cast(