alembic 1.12.1__py3-none-any.whl → 1.13.1__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 (47) hide show
  1. alembic/__init__.py +1 -3
  2. alembic/autogenerate/__init__.py +10 -10
  3. alembic/autogenerate/api.py +8 -5
  4. alembic/autogenerate/compare.py +134 -199
  5. alembic/autogenerate/render.py +39 -24
  6. alembic/autogenerate/rewriter.py +26 -13
  7. alembic/command.py +7 -2
  8. alembic/config.py +20 -9
  9. alembic/context.pyi +12 -6
  10. alembic/ddl/__init__.py +1 -1
  11. alembic/ddl/_autogen.py +325 -0
  12. alembic/ddl/base.py +12 -9
  13. alembic/ddl/impl.py +110 -13
  14. alembic/ddl/mssql.py +4 -1
  15. alembic/ddl/mysql.py +9 -6
  16. alembic/ddl/oracle.py +4 -1
  17. alembic/ddl/postgresql.py +147 -73
  18. alembic/ddl/sqlite.py +8 -6
  19. alembic/op.pyi +46 -8
  20. alembic/operations/base.py +70 -14
  21. alembic/operations/batch.py +7 -8
  22. alembic/operations/ops.py +53 -31
  23. alembic/operations/schemaobj.py +5 -4
  24. alembic/operations/toimpl.py +8 -5
  25. alembic/runtime/environment.py +17 -7
  26. alembic/runtime/migration.py +27 -11
  27. alembic/script/base.py +34 -27
  28. alembic/script/revision.py +30 -17
  29. alembic/script/write_hooks.py +3 -0
  30. alembic/templates/async/alembic.ini.mako +3 -3
  31. alembic/templates/generic/alembic.ini.mako +3 -3
  32. alembic/templates/multidb/alembic.ini.mako +3 -3
  33. alembic/testing/requirements.py +12 -0
  34. alembic/testing/schemacompare.py +9 -0
  35. alembic/util/__init__.py +31 -31
  36. alembic/util/compat.py +25 -9
  37. alembic/util/langhelpers.py +78 -33
  38. alembic/util/messaging.py +6 -3
  39. alembic/util/pyfiles.py +7 -3
  40. alembic/util/sqla_compat.py +52 -26
  41. {alembic-1.12.1.dist-info → alembic-1.13.1.dist-info}/METADATA +5 -4
  42. alembic-1.13.1.dist-info/RECORD +83 -0
  43. {alembic-1.12.1.dist-info → alembic-1.13.1.dist-info}/WHEEL +1 -1
  44. alembic-1.12.1.dist-info/RECORD +0 -82
  45. {alembic-1.12.1.dist-info → alembic-1.13.1.dist-info}/LICENSE +0 -0
  46. {alembic-1.12.1.dist-info → alembic-1.13.1.dist-info}/entry_points.txt +0 -0
  47. {alembic-1.12.1.dist-info → alembic-1.13.1.dist-info}/top_level.txt +0 -0
@@ -5,33 +5,46 @@ from collections.abc import Iterable
5
5
  import textwrap
6
6
  from typing import Any
7
7
  from typing import Callable
8
+ from typing import cast
8
9
  from typing import Dict
9
10
  from typing import List
10
11
  from typing import Mapping
12
+ from typing import MutableMapping
13
+ from typing import NoReturn
11
14
  from typing import Optional
12
15
  from typing import overload
13
16
  from typing import Sequence
17
+ from typing import Set
14
18
  from typing import Tuple
19
+ from typing import Type
20
+ from typing import TYPE_CHECKING
15
21
  from typing import TypeVar
16
22
  from typing import Union
17
23
  import uuid
18
24
  import warnings
19
25
 
20
- from sqlalchemy.util import asbool # noqa
21
- from sqlalchemy.util import immutabledict # noqa
22
- from sqlalchemy.util import memoized_property # noqa
23
- from sqlalchemy.util import to_list # noqa
24
- from sqlalchemy.util import unique_list # noqa
26
+ from sqlalchemy.util import asbool as asbool # noqa: F401
27
+ from sqlalchemy.util import immutabledict as immutabledict # noqa: F401
28
+ from sqlalchemy.util import to_list as to_list # noqa: F401
29
+ from sqlalchemy.util import unique_list as unique_list
25
30
 
26
31
  from .compat import inspect_getfullargspec
27
32
 
33
+ if True:
34
+ # zimports workaround :(
35
+ from sqlalchemy.util import ( # noqa: F401
36
+ memoized_property as memoized_property,
37
+ )
38
+
28
39
 
29
40
  EMPTY_DICT: Mapping[Any, Any] = immutabledict()
30
- _T = TypeVar("_T")
41
+ _T = TypeVar("_T", bound=Any)
42
+
43
+ _C = TypeVar("_C", bound=Callable[..., Any])
31
44
 
32
45
 
33
46
  class _ModuleClsMeta(type):
34
- def __setattr__(cls, key: str, value: Callable) -> None:
47
+ def __setattr__(cls, key: str, value: Callable[..., Any]) -> None:
35
48
  super().__setattr__(key, value)
36
49
  cls._update_module_proxies(key) # type: ignore
37
50
 
@@ -45,9 +58,13 @@ class ModuleClsProxy(metaclass=_ModuleClsMeta):
45
58
 
46
59
  """
47
60
 
48
- _setups: Dict[type, Tuple[set, list]] = collections.defaultdict(
49
- lambda: (set(), [])
50
- )
61
+ _setups: Dict[
62
+ Type[Any],
63
+ Tuple[
64
+ Set[str],
65
+ List[Tuple[MutableMapping[str, Any], MutableMapping[str, Any]]],
66
+ ],
67
+ ] = collections.defaultdict(lambda: (set(), []))
51
68
 
52
69
  @classmethod
53
70
  def _update_module_proxies(cls, name: str) -> None:
@@ -70,18 +87,33 @@ class ModuleClsProxy(metaclass=_ModuleClsMeta):
70
87
  del globals_[attr_name]
71
88
 
72
89
  @classmethod
73
- def create_module_class_proxy(cls, globals_, locals_):
90
+ def create_module_class_proxy(
91
+ cls,
92
+ globals_: MutableMapping[str, Any],
93
+ locals_: MutableMapping[str, Any],
94
+ ) -> None:
74
95
  attr_names, modules = cls._setups[cls]
75
96
  modules.append((globals_, locals_))
76
97
  cls._setup_proxy(globals_, locals_, attr_names)
77
98
 
78
99
  @classmethod
79
- def _setup_proxy(cls, globals_, locals_, attr_names):
100
+ def _setup_proxy(
101
+ cls,
102
+ globals_: MutableMapping[str, Any],
103
+ locals_: MutableMapping[str, Any],
104
+ attr_names: Set[str],
105
+ ) -> None:
80
106
  for methname in dir(cls):
81
107
  cls._add_proxied_attribute(methname, globals_, locals_, attr_names)
82
108
 
83
109
  @classmethod
84
- def _add_proxied_attribute(cls, methname, globals_, locals_, attr_names):
110
+ def _add_proxied_attribute(
111
+ cls,
112
+ methname: str,
113
+ globals_: MutableMapping[str, Any],
114
+ locals_: MutableMapping[str, Any],
115
+ attr_names: Set[str],
116
+ ) -> None:
85
117
  if not methname.startswith("_"):
86
118
  meth = getattr(cls, methname)
87
119
  if callable(meth):
@@ -92,10 +124,15 @@ class ModuleClsProxy(metaclass=_ModuleClsMeta):
92
124
  attr_names.add(methname)
93
125
 
94
126
  @classmethod
95
- def _create_method_proxy(cls, name, globals_, locals_):
127
+ def _create_method_proxy(
128
+ cls,
129
+ name: str,
130
+ globals_: MutableMapping[str, Any],
131
+ locals_: MutableMapping[str, Any],
132
+ ) -> Callable[..., Any]:
96
133
  fn = getattr(cls, name)
97
134
 
98
- def _name_error(name, from_):
135
+ def _name_error(name: str, from_: Exception) -> NoReturn:
99
136
  raise NameError(
100
137
  "Can't invoke function '%s', as the proxy object has "
101
138
  "not yet been "
@@ -119,7 +156,9 @@ class ModuleClsProxy(metaclass=_ModuleClsMeta):
119
156
  translations,
120
157
  )
121
158
 
122
- def translate(fn_name, spec, translations, args, kw):
159
+ def translate(
160
+ fn_name: str, spec: Any, translations: Any, args: Any, kw: Any
161
+ ) -> Any:
123
162
  return_kw = {}
124
163
  return_args = []
125
164
 
@@ -176,15 +215,15 @@ class ModuleClsProxy(metaclass=_ModuleClsMeta):
176
215
  "doc": fn.__doc__,
177
216
  }
178
217
  )
179
- lcl = {}
218
+ lcl: MutableMapping[str, Any] = {}
180
219
 
181
- exec(func_text, globals_, lcl)
182
- return lcl[name]
220
+ exec(func_text, cast("Dict[str, Any]", globals_), lcl)
221
+ return cast("Callable[..., Any]", lcl[name])
183
222
 
184
223
 
185
- def _with_legacy_names(translations):
186
- def decorate(fn):
187
- fn._legacy_translations = translations
224
+ def _with_legacy_names(translations: Any) -> Any:
225
+ def decorate(fn: _C) -> _C:
226
+ fn._legacy_translations = translations # type: ignore[attr-defined]
188
227
  return fn
189
228
 
190
229
  return decorate
@@ -195,21 +234,25 @@ def rev_id() -> str:
195
234
 
196
235
 
197
236
  @overload
198
- def to_tuple(x: Any, default: tuple) -> tuple:
237
+ def to_tuple(x: Any, default: Tuple[Any, ...]) -> Tuple[Any, ...]:
199
238
  ...
200
239
 
201
240
 
202
241
  @overload
203
- def to_tuple(x: None, default: Optional[_T] = None) -> _T:
242
+ def to_tuple(x: None, default: Optional[_T] = ...) -> _T:
204
243
  ...
205
244
 
206
245
 
207
246
  @overload
208
- def to_tuple(x: Any, default: Optional[tuple] = None) -> tuple:
247
+ def to_tuple(
248
+ x: Any, default: Optional[Tuple[Any, ...]] = None
249
+ ) -> Tuple[Any, ...]:
209
250
  ...
210
251
 
211
252
 
212
- def to_tuple(x, default=None):
253
+ def to_tuple(
254
+ x: Any, default: Optional[Tuple[Any, ...]] = None
255
+ ) -> Optional[Tuple[Any, ...]]:
213
256
  if x is None:
214
257
  return default
215
258
  elif isinstance(x, str):
@@ -226,13 +269,13 @@ def dedupe_tuple(tup: Tuple[str, ...]) -> Tuple[str, ...]:
226
269
 
227
270
  class Dispatcher:
228
271
  def __init__(self, uselist: bool = False) -> None:
229
- self._registry: Dict[tuple, Any] = {}
272
+ self._registry: Dict[Tuple[Any, ...], Any] = {}
230
273
  self.uselist = uselist
231
274
 
232
275
  def dispatch_for(
233
276
  self, target: Any, qualifier: str = "default"
234
- ) -> Callable:
235
- def decorate(fn):
277
+ ) -> Callable[[_C], _C]:
278
+ def decorate(fn: _C) -> _C:
236
279
  if self.uselist:
237
280
  self._registry.setdefault((target, qualifier), []).append(fn)
238
281
  else:
@@ -244,7 +287,7 @@ class Dispatcher:
244
287
 
245
288
  def dispatch(self, obj: Any, qualifier: str = "default") -> Any:
246
289
  if isinstance(obj, str):
247
- targets: Sequence = [obj]
290
+ targets: Sequence[Any] = [obj]
248
291
  elif isinstance(obj, type):
249
292
  targets = obj.__mro__
250
293
  else:
@@ -259,11 +302,13 @@ class Dispatcher:
259
302
  raise ValueError("no dispatch function for object: %s" % obj)
260
303
 
261
304
  def _fn_or_list(
262
- self, fn_or_list: Union[List[Callable], Callable]
263
- ) -> Callable:
305
+ self, fn_or_list: Union[List[Callable[..., Any]], Callable[..., Any]]
306
+ ) -> Callable[..., Any]:
264
307
  if self.uselist:
265
308
 
266
- def go(*arg, **kw):
309
+ def go(*arg: Any, **kw: Any) -> None:
310
+ if TYPE_CHECKING:
311
+ assert isinstance(fn_or_list, Sequence)
267
312
  for fn in fn_or_list:
268
313
  fn(*arg, **kw)
269
314
 
alembic/util/messaging.py CHANGED
@@ -5,6 +5,7 @@ from contextlib import contextmanager
5
5
  import logging
6
6
  import sys
7
7
  import textwrap
8
+ from typing import Iterator
8
9
  from typing import Optional
9
10
  from typing import TextIO
10
11
  from typing import Union
@@ -53,7 +54,9 @@ def write_outstream(
53
54
 
54
55
 
55
56
  @contextmanager
56
- def status(status_msg: str, newline: bool = False, quiet: bool = False):
57
+ def status(
58
+ status_msg: str, newline: bool = False, quiet: bool = False
59
+ ) -> Iterator[None]:
57
60
  msg(status_msg + " ...", newline, flush=True, quiet=quiet)
58
61
  try:
59
62
  yield
@@ -66,7 +69,7 @@ def status(status_msg: str, newline: bool = False, quiet: bool = False):
66
69
  write_outstream(sys.stdout, " done\n")
67
70
 
68
71
 
69
- def err(message: str, quiet: bool = False):
72
+ def err(message: str, quiet: bool = False) -> None:
70
73
  log.error(message)
71
74
  msg(f"FAILED: {message}", quiet=quiet)
72
75
  sys.exit(-1)
@@ -74,7 +77,7 @@ def err(message: str, quiet: bool = False):
74
77
 
75
78
  def obfuscate_url_pw(input_url: str) -> str:
76
79
  u = url.make_url(input_url)
77
- return sqla_compat.url_render_as_string(u, hide_password=True)
80
+ return sqla_compat.url_render_as_string(u, hide_password=True) # type: ignore # noqa: E501
78
81
 
79
82
 
80
83
  def warn(msg: str, stacklevel: int = 2) -> None:
alembic/util/pyfiles.py CHANGED
@@ -8,6 +8,8 @@ import importlib.util
8
8
  import os
9
9
  import re
10
10
  import tempfile
11
+ from types import ModuleType
12
+ from typing import Any
11
13
  from typing import Optional
12
14
 
13
15
  from mako import exceptions
@@ -18,7 +20,7 @@ from .exc import CommandError
18
20
 
19
21
 
20
22
  def template_to_file(
21
- template_file: str, dest: str, output_encoding: str, **kw
23
+ template_file: str, dest: str, output_encoding: str, **kw: Any
22
24
  ) -> None:
23
25
  template = Template(filename=template_file)
24
26
  try:
@@ -82,7 +84,7 @@ def pyc_file_from_path(path: str) -> Optional[str]:
82
84
  return None
83
85
 
84
86
 
85
- def load_python_file(dir_: str, filename: str):
87
+ def load_python_file(dir_: str, filename: str) -> ModuleType:
86
88
  """Load a file from the given path as a Python module."""
87
89
 
88
90
  module_id = re.sub(r"\W", "_", filename)
@@ -99,10 +101,12 @@ def load_python_file(dir_: str, filename: str):
99
101
  module = load_module_py(module_id, pyc_path)
100
102
  elif ext in (".pyc", ".pyo"):
101
103
  module = load_module_py(module_id, path)
104
+ else:
105
+ assert False
102
106
  return module
103
107
 
104
108
 
105
- def load_module_py(module_id: str, path: str):
109
+ def load_module_py(module_id: str, path: str) -> ModuleType:
106
110
  spec = importlib.util.spec_from_file_location(module_id, path)
107
111
  assert spec
108
112
  module = importlib.util.module_from_spec(spec)
@@ -1,13 +1,20 @@
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 contextlib
4
7
  import re
5
8
  from typing import Any
9
+ from typing import Callable
6
10
  from typing import Dict
7
11
  from typing import Iterable
8
12
  from typing import Iterator
9
13
  from typing import Mapping
10
14
  from typing import Optional
15
+ from typing import Protocol
16
+ from typing import Set
17
+ from typing import Type
11
18
  from typing import TYPE_CHECKING
12
19
  from typing import TypeVar
13
20
  from typing import Union
@@ -18,7 +25,6 @@ from sqlalchemy import schema
18
25
  from sqlalchemy import sql
19
26
  from sqlalchemy import types as sqltypes
20
27
  from sqlalchemy.engine import url
21
- from sqlalchemy.ext.compiler import compiles
22
28
  from sqlalchemy.schema import CheckConstraint
23
29
  from sqlalchemy.schema import Column
24
30
  from sqlalchemy.schema import ForeignKeyConstraint
@@ -33,6 +39,7 @@ from sqlalchemy.sql.visitors import traverse
33
39
  from typing_extensions import TypeGuard
34
40
 
35
41
  if TYPE_CHECKING:
42
+ from sqlalchemy import ClauseElement
36
43
  from sqlalchemy import Index
37
44
  from sqlalchemy import Table
38
45
  from sqlalchemy.engine import Connection
@@ -51,6 +58,11 @@ if TYPE_CHECKING:
51
58
  _CE = TypeVar("_CE", bound=Union["ColumnElement[Any]", "SchemaItem"])
52
59
 
53
60
 
61
+ class _CompilerProtocol(Protocol):
62
+ def __call__(self, element: Any, compiler: Any, **kw: Any) -> str:
63
+ ...
64
+
65
+
54
66
  def _safe_int(value: str) -> Union[int, str]:
55
67
  try:
56
68
  return int(value)
@@ -70,7 +82,7 @@ sqla_2 = _vers >= (2,)
70
82
  sqlalchemy_version = __version__
71
83
 
72
84
  try:
73
- from sqlalchemy.sql.naming import _NONE_NAME as _NONE_NAME
85
+ from sqlalchemy.sql.naming import _NONE_NAME as _NONE_NAME # type: ignore[attr-defined] # noqa: E501
74
86
  except ImportError:
75
87
  from sqlalchemy.sql.elements import _NONE_NAME as _NONE_NAME # type: ignore # noqa: E501
76
88
 
@@ -79,8 +91,18 @@ class _Unsupported:
79
91
  "Placeholder for unsupported SQLAlchemy classes"
80
92
 
81
93
 
94
+ if TYPE_CHECKING:
95
+
96
+ def compiles(
97
+ element: Type[ClauseElement], *dialects: str
98
+ ) -> Callable[[_CompilerProtocol], _CompilerProtocol]:
99
+ ...
100
+
101
+ else:
102
+ from sqlalchemy.ext.compiler import compiles
103
+
82
104
  try:
83
- from sqlalchemy import Computed
105
+ from sqlalchemy import Computed as Computed
84
106
  except ImportError:
85
107
  if not TYPE_CHECKING:
86
108
 
@@ -94,7 +116,7 @@ else:
94
116
  has_computed_reflection = _vers >= (1, 3, 16)
95
117
 
96
118
  try:
97
- from sqlalchemy import Identity
119
+ from sqlalchemy import Identity as Identity
98
120
  except ImportError:
99
121
  if not TYPE_CHECKING:
100
122
 
@@ -250,7 +272,7 @@ def _idx_table_bound_expressions(idx: Index) -> Iterable[ColumnElement[Any]]:
250
272
 
251
273
  def _copy(schema_item: _CE, **kw) -> _CE:
252
274
  if hasattr(schema_item, "_copy"):
253
- return schema_item._copy(**kw) # type: ignore[union-attr]
275
+ return schema_item._copy(**kw)
254
276
  else:
255
277
  return schema_item.copy(**kw) # type: ignore[union-attr]
256
278
 
@@ -368,7 +390,12 @@ else:
368
390
  return type_.impl, type_.mapping
369
391
 
370
392
 
371
- def _fk_spec(constraint):
393
+ def _fk_spec(constraint: ForeignKeyConstraint) -> Any:
394
+ if TYPE_CHECKING:
395
+ assert constraint.columns is not None
396
+ assert constraint.elements is not None
397
+ assert isinstance(constraint.parent, Table)
398
+
372
399
  source_columns = [
373
400
  constraint.columns[key].name for key in constraint.column_keys
374
401
  ]
@@ -397,7 +424,7 @@ def _fk_spec(constraint):
397
424
 
398
425
 
399
426
  def _fk_is_self_referential(constraint: ForeignKeyConstraint) -> bool:
400
- spec = constraint.elements[0]._get_colspec() # type: ignore[attr-defined]
427
+ spec = constraint.elements[0]._get_colspec()
401
428
  tokens = spec.split(".")
402
429
  tokens.pop(-1) # colname
403
430
  tablekey = ".".join(tokens)
@@ -409,13 +436,13 @@ def _is_type_bound(constraint: Constraint) -> bool:
409
436
  # this deals with SQLAlchemy #3260, don't copy CHECK constraints
410
437
  # that will be generated by the type.
411
438
  # new feature added for #3260
412
- return constraint._type_bound # type: ignore[attr-defined]
439
+ return constraint._type_bound
413
440
 
414
441
 
415
442
  def _find_columns(clause):
416
443
  """locate Column objects within the given expression."""
417
444
 
418
- cols = set()
445
+ cols: Set[ColumnElement[Any]] = set()
419
446
  traverse(clause, {}, {"column": cols.add})
420
447
  return cols
421
448
 
@@ -524,14 +551,6 @@ def _render_literal_bindparam(
524
551
  return compiler.render_literal_bindparam(element, **kw)
525
552
 
526
553
 
527
- def _get_index_expressions(idx):
528
- return list(idx.expressions)
529
-
530
-
531
- def _get_index_column_names(idx):
532
- return [getattr(exp, "name", None) for exp in _get_index_expressions(idx)]
533
-
534
-
535
554
  def _column_kwargs(col: Column) -> Mapping:
536
555
  if sqla_13:
537
556
  return col.kwargs
@@ -570,9 +589,7 @@ def _get_constraint_final_name(
570
589
  if isinstance(constraint, schema.Index):
571
590
  # name should not be quoted.
572
591
  d = dialect.ddl_compiler(dialect, None) # type: ignore[arg-type]
573
- return d._prepared_index_name( # type: ignore[attr-defined]
574
- constraint
575
- )
592
+ return d._prepared_index_name(constraint)
576
593
  else:
577
594
  # name should not be quoted.
578
595
  return dialect.identifier_preparer.format_constraint(constraint)
@@ -616,7 +633,11 @@ def _insert_inline(table: Union[TableClause, Table]) -> Insert:
616
633
 
617
634
  if sqla_14:
618
635
  from sqlalchemy import create_mock_engine
619
- from sqlalchemy import select as _select
636
+
637
+ # weird mypy workaround
638
+ from sqlalchemy import select as _sa_select
639
+
640
+ _select = _sa_select
620
641
  else:
621
642
  from sqlalchemy import create_engine
622
643
 
@@ -625,15 +646,20 @@ else:
625
646
  "postgresql://", strategy="mock", executor=executor
626
647
  )
627
648
 
628
- def _select(*columns, **kw) -> Select: # type: ignore[no-redef]
649
+ def _select(*columns, **kw) -> Select:
629
650
  return sql.select(list(columns), **kw) # type: ignore[call-overload]
630
651
 
631
652
 
632
653
  def is_expression_index(index: Index) -> bool:
633
- expr: Any
634
654
  for expr in index.expressions:
635
- while isinstance(expr, UnaryExpression):
636
- expr = expr.element
637
- if not isinstance(expr, ColumnClause) or expr.is_literal:
655
+ if is_expression(expr):
638
656
  return True
639
657
  return False
658
+
659
+
660
+ def is_expression(expr: Any) -> bool:
661
+ while isinstance(expr, UnaryExpression):
662
+ expr = expr.element
663
+ if not isinstance(expr, ColumnClause) or expr.is_literal:
664
+ return True
665
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: alembic
3
- Version: 1.12.1
3
+ Version: 1.13.1
4
4
  Summary: A database migration tool for SQLAlchemy.
5
5
  Home-page: https://alembic.sqlalchemy.org
6
6
  Author: Mike Bayer
@@ -17,14 +17,15 @@ Classifier: License :: OSI Approved :: MIT License
17
17
  Classifier: Operating System :: OS Independent
18
18
  Classifier: Programming Language :: Python
19
19
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.7
21
20
  Classifier: Programming Language :: Python :: 3.8
22
21
  Classifier: Programming Language :: Python :: 3.9
23
22
  Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
24
25
  Classifier: Programming Language :: Python :: Implementation :: CPython
25
26
  Classifier: Programming Language :: Python :: Implementation :: PyPy
26
27
  Classifier: Topic :: Database :: Front-Ends
27
- Requires-Python: >=3.7
28
+ Requires-Python: >=3.8
28
29
  Description-Content-Type: text/x-rst
29
30
  License-File: LICENSE
30
31
  Requires-Dist: SQLAlchemy >=1.3.0
@@ -33,7 +34,7 @@ Requires-Dist: typing-extensions >=4
33
34
  Requires-Dist: importlib-metadata ; python_version < "3.9"
34
35
  Requires-Dist: importlib-resources ; python_version < "3.9"
35
36
  Provides-Extra: tz
36
- Requires-Dist: python-dateutil ; extra == 'tz'
37
+ Requires-Dist: backports.zoneinfo ; (python_version < "3.9") and extra == 'tz'
37
38
 
38
39
  Alembic is a database migrations tool written by the author
39
40
  of `SQLAlchemy <http://www.sqlalchemy.org>`_. A migrations tool
@@ -0,0 +1,83 @@
1
+ alembic/__init__.py,sha256=PMiQT_1tHyC_Od3GDBArBk7r14v8F62_xkzliPq9tLU,63
2
+ alembic/__main__.py,sha256=373m7-TBh72JqrSMYviGrxCHZo-cnweM8AGF8A22PmY,78
3
+ alembic/command.py,sha256=jWFNS-wPWA-Klfm0GsPfWh_8sPj4n7rKROJ0zrwhoR0,21712
4
+ alembic/config.py,sha256=I12lm4V-AXSt-7nvub-Vtx5Zfa68pYP5xSrFQQd45rQ,22256
5
+ alembic/context.py,sha256=hK1AJOQXJ29Bhn276GYcosxeG7pC5aZRT5E8c4bMJ4Q,195
6
+ alembic/context.pyi,sha256=hUHbSnbSeEEMVkk0gDSXOq4_9edSjYzsjmmf-mL9Iao,31737
7
+ alembic/environment.py,sha256=MM5lPayGT04H3aeng1H7GQ8HEAs3VGX5yy6mDLCPLT4,43
8
+ alembic/migration.py,sha256=MV6Fju6rZtn2fTREKzXrCZM6aIBGII4OMZFix0X-GLs,41
9
+ alembic/op.py,sha256=flHtcsVqOD-ZgZKK2pv-CJ5Cwh-KJ7puMUNXzishxLw,167
10
+ alembic/op.pyi,sha256=8R6SJr1dQharU0blmMJJj23XFO_hk9ZmAQBJBQOeXRU,49816
11
+ alembic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ alembic/autogenerate/__init__.py,sha256=ntmUTXhjLm4_zmqIwyVaECdpPDn6_u1yM9vYk6-553E,543
13
+ alembic/autogenerate/api.py,sha256=Oc7MRtDhkSICsQ82fYP9bBMYaAjzzW2X_izM3AQU-OY,22171
14
+ alembic/autogenerate/compare.py,sha256=3QLK2yCDW37bXbAIXcHGz4YOFlOW8bSfLHJ8bmzgG1M,44938
15
+ alembic/autogenerate/render.py,sha256=uSbCpkh72mo00xGZ8CJa3teM_gqulCoNtxH0Ey8Ny1k,34939
16
+ alembic/autogenerate/rewriter.py,sha256=uZWRkTYJoncoEJ5WY1QBRiozjyChqZDJPy4LtcRibjM,7846
17
+ alembic/ddl/__init__.py,sha256=Df8fy4Vn_abP8B7q3x8gyFwEwnLw6hs2Ljt_bV3EZWE,152
18
+ alembic/ddl/_autogen.py,sha256=0no9ywWP8gjvO57Ozc2naab4qNusVNn2fiJekjc275g,9179
19
+ alembic/ddl/base.py,sha256=Jd7oPoAOGjOMcdMUIzSKnTjd8NKnTd7IjBXXyVpDCkU,9955
20
+ alembic/ddl/impl.py,sha256=vkhkXFpLPJBG9jW2kv_sR5CC5czNd1ERLjLtfLuOFP0,28778
21
+ alembic/ddl/mssql.py,sha256=ydvgBSaftKYjaBaMyqius66Ta4CICQSj79Og3Ed2atY,14219
22
+ alembic/ddl/mysql.py,sha256=am221U_UK3wX33tNcXNiOObZV-Pa4CXuv7vN-epF9IU,16788
23
+ alembic/ddl/oracle.py,sha256=TmoCq_FlbfyWAAk3e_q6mMQU0YmlfIcgKHpRfNMmgr0,6211
24
+ alembic/ddl/postgresql.py,sha256=dcWLdDSqivzizVCce_H6RnOVAayPXDFfns-NC4-UaA8,29842
25
+ alembic/ddl/sqlite.py,sha256=wLXhb8bJWRspKQTb-iVfepR4LXYgOuEbUWKX5qwDhIQ,7570
26
+ alembic/operations/__init__.py,sha256=e0KQSZAgLpTWvyvreB7DWg7RJV_MWSOPVDgCqsd2FzY,318
27
+ alembic/operations/base.py,sha256=LCx4NH5NA2NLWQFaZTqE_p2KgLtqJ76oVcp1Grj-zFM,74004
28
+ alembic/operations/batch.py,sha256=YqtD4hJ3_RkFxvI7zbmBwxcLEyLHYyWQpsz4l5L85yI,26943
29
+ alembic/operations/ops.py,sha256=2vtYFhYFDEVq158HwORfGTsobDM7c-t0lewuR7JKw7g,94353
30
+ alembic/operations/schemaobj.py,sha256=vjoD57QvjbzzA-jyPIXulbOmb5_bGPtxoq58KsKI4Y0,9424
31
+ alembic/operations/toimpl.py,sha256=SoNY2_gZX2baXTD-pNjpCWnON8D2QBSYQBIjo13-WKA,7115
32
+ alembic/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ alembic/runtime/environment.py,sha256=9wSJaePNAXBXvirif_85ql7dSq4bXM1E6pSb2k-6uGI,41508
34
+ alembic/runtime/migration.py,sha256=Yfv2fa11wiQ0WgoZaFldlWxCPq4dVDOCEOxST_-1VB0,50066
35
+ alembic/script/__init__.py,sha256=lSj06O391Iy5avWAiq8SPs6N8RBgxkSPjP8wpXcNDGg,100
36
+ alembic/script/base.py,sha256=4gkppn2FKCYDoBgzGkTslcwdyxSabmHvGq0uGKulwbI,37586
37
+ alembic/script/revision.py,sha256=sfnXQw2UwiXs0E6gEPHBKWuSsB5KyuxZPTrFn__hIEk,62060
38
+ alembic/script/write_hooks.py,sha256=NGB6NGgfdf7HK6XNNpSKqUCfzxazj-NRUePgFx7MJSM,5036
39
+ alembic/templates/async/README,sha256=ISVtAOvqvKk_5ThM5ioJE-lMkvf9IbknFUFVU_vPma4,58
40
+ alembic/templates/async/alembic.ini.mako,sha256=uuhJETLWQuiYcs_jAOXHEjshEJ7VslEc1q4RRj0HWbE,3525
41
+ alembic/templates/async/env.py,sha256=zbOCf3Y7w2lg92hxSwmG1MM_7y56i_oRH4AKp0pQBYo,2389
42
+ alembic/templates/async/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
43
+ alembic/templates/generic/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
44
+ alembic/templates/generic/alembic.ini.mako,sha256=sT7F852yN3c8X1-GKFlhuWExXxw9hY1eb1ZZ9flFSzc,3634
45
+ alembic/templates/generic/env.py,sha256=TLRWOVW3Xpt_Tpf8JFzlnoPn_qoUu8UV77Y4o9XD6yI,2103
46
+ alembic/templates/generic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
47
+ alembic/templates/multidb/README,sha256=dWLDhnBgphA4Nzb7sNlMfCS3_06YqVbHhz-9O5JNqyI,606
48
+ alembic/templates/multidb/alembic.ini.mako,sha256=mPh8JFJfWiGs6tMtL8_HAQ-Dz1QOoJgE5Vm76nIMqgU,3728
49
+ alembic/templates/multidb/env.py,sha256=6zNjnW8mXGUk7erTsAvrfhvqoczJ-gagjVq1Ypg2YIQ,4230
50
+ alembic/templates/multidb/script.py.mako,sha256=N06nMtNSwHkgl0EBXDyMt8njp9tlOesR583gfq21nbY,1090
51
+ alembic/testing/__init__.py,sha256=kOxOh5nwmui9d-_CCq9WA4Udwy7ITjm453w74CTLZDo,1159
52
+ alembic/testing/assertions.py,sha256=1CbJk8c8-WO9eJ0XJ0jJvMsNRLUrXV41NOeIJUAlOBk,5015
53
+ alembic/testing/env.py,sha256=zJacVb_z6uLs2U1TtkmnFH9P3_F-3IfYbVv4UEPOvfo,10754
54
+ alembic/testing/fixtures.py,sha256=NyP4wE_dFN9ZzSGiBagRu1cdzkka03nwJYJYHYrrkSY,9112
55
+ alembic/testing/requirements.py,sha256=dKeAO1l5TwBqXarJN-IPORlCqCJv-41Dj6oXoEikxHQ,5133
56
+ alembic/testing/schemacompare.py,sha256=N5UqSNCOJetIKC4vKhpYzQEpj08XkdgIoqBmEPQ3tlc,4838
57
+ alembic/testing/util.py,sha256=CQrcQDA8fs_7ME85z5ydb-Bt70soIIID-qNY1vbR2dg,3350
58
+ alembic/testing/warnings.py,sha256=RxA7x_8GseANgw07Us8JN_1iGbANxaw6_VitX2ZGQH4,1078
59
+ alembic/testing/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ alembic/testing/plugin/bootstrap.py,sha256=9C6wtjGrIVztZ928w27hsQE0KcjDLIUtUN3dvZKsMVk,50
61
+ alembic/testing/suite/__init__.py,sha256=MvE7-hwbaVN1q3NM-ztGxORU9dnIelUCINKqNxewn7Y,288
62
+ alembic/testing/suite/_autogen_fixtures.py,sha256=cDq1pmzHe15S6dZPGNC6sqFaCQ3hLT_oPV2IDigUGQ0,9880
63
+ alembic/testing/suite/test_autogen_comments.py,sha256=aEGqKUDw4kHjnDk298aoGcQvXJWmZXcIX_2FxH4cJK8,6283
64
+ alembic/testing/suite/test_autogen_computed.py,sha256=qJeBpc8urnwTFvbwWrSTIbHVkRUuCXP-dKaNbUK2U2U,6077
65
+ alembic/testing/suite/test_autogen_diffs.py,sha256=T4SR1n_kmcOKYhR4W1-dA0e5sddJ69DSVL2HW96kAkE,8394
66
+ alembic/testing/suite/test_autogen_fks.py,sha256=AqFmb26Buex167HYa9dZWOk8x-JlB1OK3bwcvvjDFaU,32927
67
+ alembic/testing/suite/test_autogen_identity.py,sha256=kcuqngG7qXAKPJDX4U8sRzPKHEJECHuZ0DtuaS6tVkk,5824
68
+ alembic/testing/suite/test_environment.py,sha256=w9F0xnLEbALeR8k6_-Tz6JHvy91IqiTSypNasVzXfZQ,11877
69
+ alembic/testing/suite/test_op.py,sha256=2XQCdm_NmnPxHGuGj7hmxMzIhKxXNotUsKdACXzE1mM,1343
70
+ alembic/util/__init__.py,sha256=KSZ7UT2YzH6CietgUtljVoE3QnGjoFKOi7RL5sgUxrk,1688
71
+ alembic/util/compat.py,sha256=RjHdQa1NomU3Zlvgfvza0OMiSRQSLRL3xVl3OdUy2UE,2594
72
+ alembic/util/editor.py,sha256=JIz6_BdgV8_oKtnheR6DZoB7qnrHrlRgWjx09AsTsUw,2546
73
+ alembic/util/exc.py,sha256=KQTru4zcgAmN4IxLMwLFS56XToUewaXB7oOLcPNjPwg,98
74
+ alembic/util/langhelpers.py,sha256=KYyOjFjJ26evPmrwhdTvLQNXN0bK7AIy5sRdKD91Fvg,10038
75
+ alembic/util/messaging.py,sha256=BM5OCZ6qmLftFRw5yPSxj539_QmfVwNYoU8qYsDqoJY,3132
76
+ alembic/util/pyfiles.py,sha256=zltVdcwEJJCPS2gHsQvkHkQakuF6wXiZ6zfwHbGNT0g,3489
77
+ alembic/util/sqla_compat.py,sha256=toD1S63PgZ6iEteP9bwIf5E7DIUdQPo0UQ_Fn18qWnI,19536
78
+ alembic-1.13.1.dist-info/LICENSE,sha256=soUmiob0QW6vTQWyrjiAwVb3xZqPk1pAK8BW6vszrwg,1058
79
+ alembic-1.13.1.dist-info/METADATA,sha256=W1F2NBRkhqW55HiGmEIpdmiRt2skU5wwJd21UHFbSdQ,7390
80
+ alembic-1.13.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
81
+ alembic-1.13.1.dist-info/entry_points.txt,sha256=aykM30soxwGN0pB7etLc1q0cHJbL9dy46RnK9VX4LLw,48
82
+ alembic-1.13.1.dist-info/top_level.txt,sha256=FwKWd5VsPFC8iQjpu1u9Cn-JnK3-V1RhUCmWqz1cl-s,8
83
+ alembic-1.13.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: bdist_wheel (0.42.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5