alembic 1.15.2__py3-none-any.whl → 1.16.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 (41) hide show
  1. alembic/__init__.py +1 -1
  2. alembic/autogenerate/compare.py +60 -7
  3. alembic/autogenerate/render.py +25 -4
  4. alembic/command.py +112 -37
  5. alembic/config.py +574 -222
  6. alembic/ddl/base.py +31 -7
  7. alembic/ddl/impl.py +23 -5
  8. alembic/ddl/mssql.py +3 -1
  9. alembic/ddl/mysql.py +8 -4
  10. alembic/ddl/postgresql.py +6 -2
  11. alembic/ddl/sqlite.py +1 -1
  12. alembic/op.pyi +24 -5
  13. alembic/operations/base.py +18 -3
  14. alembic/operations/ops.py +49 -8
  15. alembic/operations/toimpl.py +20 -3
  16. alembic/script/base.py +123 -136
  17. alembic/script/revision.py +1 -1
  18. alembic/script/write_hooks.py +20 -21
  19. alembic/templates/async/alembic.ini.mako +40 -16
  20. alembic/templates/generic/alembic.ini.mako +39 -17
  21. alembic/templates/multidb/alembic.ini.mako +42 -17
  22. alembic/templates/pyproject/README +1 -0
  23. alembic/templates/pyproject/alembic.ini.mako +44 -0
  24. alembic/templates/pyproject/env.py +78 -0
  25. alembic/templates/pyproject/pyproject.toml.mako +76 -0
  26. alembic/templates/pyproject/script.py.mako +28 -0
  27. alembic/testing/__init__.py +2 -0
  28. alembic/testing/assertions.py +4 -0
  29. alembic/testing/env.py +56 -1
  30. alembic/testing/fixtures.py +28 -1
  31. alembic/testing/suite/_autogen_fixtures.py +113 -0
  32. alembic/util/__init__.py +1 -0
  33. alembic/util/compat.py +56 -0
  34. alembic/util/messaging.py +4 -0
  35. alembic/util/pyfiles.py +56 -19
  36. {alembic-1.15.2.dist-info → alembic-1.16.1.dist-info}/METADATA +3 -3
  37. {alembic-1.15.2.dist-info → alembic-1.16.1.dist-info}/RECORD +41 -36
  38. {alembic-1.15.2.dist-info → alembic-1.16.1.dist-info}/WHEEL +1 -1
  39. {alembic-1.15.2.dist-info → alembic-1.16.1.dist-info}/entry_points.txt +0 -0
  40. {alembic-1.15.2.dist-info → alembic-1.16.1.dist-info}/licenses/LICENSE +0 -0
  41. {alembic-1.15.2.dist-info → alembic-1.16.1.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,9 @@ from __future__ import annotations
3
3
  import configparser
4
4
  from contextlib import contextmanager
5
5
  import io
6
+ import os
6
7
  import re
8
+ import shutil
7
9
  from typing import Any
8
10
  from typing import Dict
9
11
 
@@ -24,13 +26,13 @@ from sqlalchemy.testing.fixtures import TestBase as SQLAlchemyTestBase
24
26
 
25
27
  import alembic
26
28
  from .assertions import _get_dialect
29
+ from .env import _get_staging_directory
27
30
  from ..environment import EnvironmentContext
28
31
  from ..migration import MigrationContext
29
32
  from ..operations import Operations
30
33
  from ..util import sqla_compat
31
34
  from ..util.sqla_compat import sqla_2
32
35
 
33
-
34
36
  testing_config = configparser.ConfigParser()
35
37
  testing_config.read(["test.cfg"])
36
38
 
@@ -38,6 +40,31 @@ testing_config.read(["test.cfg"])
38
40
  class TestBase(SQLAlchemyTestBase):
39
41
  is_sqlalchemy_future = sqla_2
40
42
 
43
+ @testing.fixture()
44
+ def clear_staging_dir(self):
45
+ yield
46
+ location = _get_staging_directory()
47
+ for filename in os.listdir(location):
48
+ file_path = os.path.join(location, filename)
49
+ if os.path.isfile(file_path) or os.path.islink(file_path):
50
+ os.unlink(file_path)
51
+ elif os.path.isdir(file_path):
52
+ shutil.rmtree(file_path)
53
+
54
+ @contextmanager
55
+ def pushd(self, dirname):
56
+ current_dir = os.getcwd()
57
+ try:
58
+ os.chdir(dirname)
59
+ yield
60
+ finally:
61
+ os.chdir(current_dir)
62
+
63
+ @testing.fixture()
64
+ def pop_alembic_config_env(self):
65
+ yield
66
+ os.environ.pop("ALEMBIC_CONFIG", None)
67
+
41
68
  @testing.fixture()
42
69
  def ops_context(self, migration_context):
43
70
  with migration_context.begin_transaction(_per_migration=True):
@@ -14,6 +14,7 @@ from sqlalchemy import inspect
14
14
  from sqlalchemy import Integer
15
15
  from sqlalchemy import MetaData
16
16
  from sqlalchemy import Numeric
17
+ from sqlalchemy import PrimaryKeyConstraint
17
18
  from sqlalchemy import String
18
19
  from sqlalchemy import Table
19
20
  from sqlalchemy import Text
@@ -149,6 +150,118 @@ class ModelOne:
149
150
  return m
150
151
 
151
152
 
153
+ class NamingConvModel:
154
+ __requires__ = ("unique_constraint_reflection",)
155
+ configure_opts = {"conv_all_constraint_names": True}
156
+ naming_convention = {
157
+ "ix": "ix_%(column_0_label)s",
158
+ "uq": "uq_%(table_name)s_%(constraint_name)s",
159
+ "ck": "ck_%(table_name)s_%(constraint_name)s",
160
+ "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
161
+ "pk": "pk_%(table_name)s",
162
+ }
163
+
164
+ @classmethod
165
+ def _get_db_schema(cls):
166
+ # database side - assume all constraints have a name that
167
+ # we would assume here is a "db generated" name. need to make
168
+ # sure these all render with op.f().
169
+ m = MetaData()
170
+ Table(
171
+ "x1",
172
+ m,
173
+ Column("q", Integer),
174
+ Index("db_x1_index_q", "q"),
175
+ PrimaryKeyConstraint("q", name="db_x1_primary_q"),
176
+ )
177
+ Table(
178
+ "x2",
179
+ m,
180
+ Column("q", Integer),
181
+ Column("p", ForeignKey("x1.q", name="db_x2_foreign_q")),
182
+ CheckConstraint("q > 5", name="db_x2_check_q"),
183
+ )
184
+ Table(
185
+ "x3",
186
+ m,
187
+ Column("q", Integer),
188
+ Column("r", Integer),
189
+ Column("s", Integer),
190
+ UniqueConstraint("q", name="db_x3_unique_q"),
191
+ )
192
+ Table(
193
+ "x4",
194
+ m,
195
+ Column("q", Integer),
196
+ PrimaryKeyConstraint("q", name="db_x4_primary_q"),
197
+ )
198
+ Table(
199
+ "x5",
200
+ m,
201
+ Column("q", Integer),
202
+ Column("p", ForeignKey("x4.q", name="db_x5_foreign_q")),
203
+ Column("r", Integer),
204
+ Column("s", Integer),
205
+ PrimaryKeyConstraint("q", name="db_x5_primary_q"),
206
+ UniqueConstraint("r", name="db_x5_unique_r"),
207
+ CheckConstraint("s > 5", name="db_x5_check_s"),
208
+ )
209
+ # SQLite and it's "no names needed" thing. bleh.
210
+ # we can't have a name for these so you'll see "None" for the name.
211
+ Table(
212
+ "unnamed_sqlite",
213
+ m,
214
+ Column("q", Integer),
215
+ Column("r", Integer),
216
+ PrimaryKeyConstraint("q"),
217
+ UniqueConstraint("r"),
218
+ )
219
+ return m
220
+
221
+ @classmethod
222
+ def _get_model_schema(cls):
223
+ from sqlalchemy.sql.naming import conv
224
+
225
+ m = MetaData(naming_convention=cls.naming_convention)
226
+ Table(
227
+ "x1", m, Column("q", Integer, primary_key=True), Index(None, "q")
228
+ )
229
+ Table(
230
+ "x2",
231
+ m,
232
+ Column("q", Integer),
233
+ Column("p", ForeignKey("x1.q")),
234
+ CheckConstraint("q > 5", name="token_x2check1"),
235
+ )
236
+ Table(
237
+ "x3",
238
+ m,
239
+ Column("q", Integer),
240
+ Column("r", Integer),
241
+ Column("s", Integer),
242
+ UniqueConstraint("r", name="token_x3r"),
243
+ UniqueConstraint("s", name=conv("userdef_x3_unique_s")),
244
+ )
245
+ Table(
246
+ "x4",
247
+ m,
248
+ Column("q", Integer, primary_key=True),
249
+ Index("userdef_x4_idx_q", "q"),
250
+ )
251
+ Table(
252
+ "x6",
253
+ m,
254
+ Column("q", Integer, primary_key=True),
255
+ Column("p", ForeignKey("x4.q")),
256
+ Column("r", Integer),
257
+ Column("s", Integer),
258
+ UniqueConstraint("r", name="token_x6r"),
259
+ CheckConstraint("s > 5", "token_x6check1"),
260
+ CheckConstraint("s < 20", conv("userdef_x6_check_s")),
261
+ )
262
+ return m
263
+
264
+
152
265
  class _ComparesFKs:
153
266
  def _assert_fk_diff(
154
267
  self,
alembic/util/__init__.py CHANGED
@@ -20,6 +20,7 @@ from .messaging import msg as msg
20
20
  from .messaging import obfuscate_url_pw as obfuscate_url_pw
21
21
  from .messaging import status as status
22
22
  from .messaging import warn as warn
23
+ from .messaging import warn_deprecated as warn_deprecated
23
24
  from .messaging import write_outstream as write_outstream
24
25
  from .pyfiles import coerce_resource_to_filename as coerce_resource_to_filename
25
26
  from .pyfiles import load_python_file as load_python_file
alembic/util/compat.py CHANGED
@@ -5,9 +5,11 @@ from __future__ import annotations
5
5
  from configparser import ConfigParser
6
6
  import io
7
7
  import os
8
+ from pathlib import Path
8
9
  import sys
9
10
  import typing
10
11
  from typing import Any
12
+ from typing import Iterator
11
13
  from typing import List
12
14
  from typing import Optional
13
15
  from typing import Sequence
@@ -24,7 +26,9 @@ if True:
24
26
 
25
27
  is_posix = os.name == "posix"
26
28
 
29
+ py314 = sys.version_info >= (3, 14)
27
30
  py313 = sys.version_info >= (3, 13)
31
+ py312 = sys.version_info >= (3, 12)
28
32
  py311 = sys.version_info >= (3, 11)
29
33
  py310 = sys.version_info >= (3, 10)
30
34
  py39 = sys.version_info >= (3, 9)
@@ -51,6 +55,58 @@ else:
51
55
  import importlib_metadata # type:ignore # noqa
52
56
  from importlib_metadata import EntryPoint # type:ignore # noqa
53
57
 
58
+ if py311:
59
+ import tomllib as tomllib
60
+ else:
61
+ import tomli as tomllib # type: ignore # noqa
62
+
63
+
64
+ if py312:
65
+
66
+ def path_walk(
67
+ path: Path, *, top_down: bool = True
68
+ ) -> Iterator[tuple[Path, list[str], list[str]]]:
69
+ return Path.walk(path)
70
+
71
+ def path_relative_to(
72
+ path: Path, other: Path, *, walk_up: bool = False
73
+ ) -> Path:
74
+ return path.relative_to(other, walk_up=walk_up)
75
+
76
+ else:
77
+
78
+ def path_walk(
79
+ path: Path, *, top_down: bool = True
80
+ ) -> Iterator[tuple[Path, list[str], list[str]]]:
81
+ for root, dirs, files in os.walk(path, topdown=top_down):
82
+ yield Path(root), dirs, files
83
+
84
+ def path_relative_to(
85
+ path: Path, other: Path, *, walk_up: bool = False
86
+ ) -> Path:
87
+ """
88
+ Calculate the relative path of 'path' with respect to 'other',
89
+ optionally allowing 'path' to be outside the subtree of 'other'.
90
+
91
+ OK I used AI for this, sorry
92
+
93
+ """
94
+ try:
95
+ return path.relative_to(other)
96
+ except ValueError:
97
+ if walk_up:
98
+ other_ancestors = list(other.parents) + [other]
99
+ for ancestor in other_ancestors:
100
+ try:
101
+ return path.relative_to(ancestor)
102
+ except ValueError:
103
+ continue
104
+ raise ValueError(
105
+ f"{path} is not in the same subtree as {other}"
106
+ )
107
+ else:
108
+ raise
109
+
54
110
 
55
111
  def importlib_metadata_get(group: str) -> Sequence[EntryPoint]:
56
112
  ep = importlib_metadata.entry_points()
alembic/util/messaging.py CHANGED
@@ -81,6 +81,10 @@ def warn(msg: str, stacklevel: int = 2) -> None:
81
81
  warnings.warn(msg, UserWarning, stacklevel=stacklevel)
82
82
 
83
83
 
84
+ def warn_deprecated(msg: str, stacklevel: int = 2) -> None:
85
+ warnings.warn(msg, DeprecationWarning, stacklevel=stacklevel)
86
+
87
+
84
88
  def msg(
85
89
  msg: str, newline: bool = True, flush: bool = False, quiet: bool = False
86
90
  ) -> None:
alembic/util/pyfiles.py CHANGED
@@ -6,11 +6,13 @@ import importlib
6
6
  import importlib.machinery
7
7
  import importlib.util
8
8
  import os
9
+ import pathlib
9
10
  import re
10
11
  import tempfile
11
12
  from types import ModuleType
12
13
  from typing import Any
13
14
  from typing import Optional
15
+ from typing import Union
14
16
 
15
17
  from mako import exceptions
16
18
  from mako.template import Template
@@ -20,9 +22,14 @@ from .exc import CommandError
20
22
 
21
23
 
22
24
  def template_to_file(
23
- template_file: str, dest: str, output_encoding: str, **kw: Any
25
+ template_file: Union[str, os.PathLike[str]],
26
+ dest: Union[str, os.PathLike[str]],
27
+ output_encoding: str,
28
+ *,
29
+ append: bool = False,
30
+ **kw: Any,
24
31
  ) -> None:
25
- template = Template(filename=template_file)
32
+ template = Template(filename=_preserving_path_as_str(template_file))
26
33
  try:
27
34
  output = template.render_unicode(**kw).encode(output_encoding)
28
35
  except:
@@ -38,11 +45,11 @@ def template_to_file(
38
45
  "template-oriented traceback." % fname
39
46
  )
40
47
  else:
41
- with open(dest, "wb") as f:
48
+ with open(dest, "ab" if append else "wb") as f:
42
49
  f.write(output)
43
50
 
44
51
 
45
- def coerce_resource_to_filename(fname: str) -> str:
52
+ def coerce_resource_to_filename(fname_or_resource: str) -> pathlib.Path:
46
53
  """Interpret a filename as either a filesystem location or as a package
47
54
  resource.
48
55
 
@@ -50,8 +57,9 @@ def coerce_resource_to_filename(fname: str) -> str:
50
57
  are interpreted as resources and coerced to a file location.
51
58
 
52
59
  """
53
- if not os.path.isabs(fname) and ":" in fname:
54
- tokens = fname.split(":")
60
+ # TODO: there seem to be zero tests for the package resource codepath
61
+ if not os.path.isabs(fname_or_resource) and ":" in fname_or_resource:
62
+ tokens = fname_or_resource.split(":")
55
63
 
56
64
  # from https://importlib-resources.readthedocs.io/en/latest/migration.html#pkg-resources-resource-filename # noqa E501
57
65
 
@@ -61,37 +69,48 @@ def coerce_resource_to_filename(fname: str) -> str:
61
69
  ref = compat.importlib_resources.files(tokens[0])
62
70
  for tok in tokens[1:]:
63
71
  ref = ref / tok
64
- fname = file_manager.enter_context( # type: ignore[assignment]
72
+ fname_or_resource = file_manager.enter_context( # type: ignore[assignment] # noqa: E501
65
73
  compat.importlib_resources.as_file(ref)
66
74
  )
67
- return fname
75
+ return pathlib.Path(fname_or_resource)
68
76
 
69
77
 
70
- def pyc_file_from_path(path: str) -> Optional[str]:
78
+ def pyc_file_from_path(
79
+ path: Union[str, os.PathLike[str]],
80
+ ) -> Optional[pathlib.Path]:
71
81
  """Given a python source path, locate the .pyc."""
72
82
 
73
- candidate = importlib.util.cache_from_source(path)
74
- if os.path.exists(candidate):
83
+ pathpath = pathlib.Path(path)
84
+ candidate = pathlib.Path(
85
+ importlib.util.cache_from_source(pathpath.as_posix())
86
+ )
87
+ if candidate.exists():
75
88
  return candidate
76
89
 
77
90
  # even for pep3147, fall back to the old way of finding .pyc files,
78
91
  # to support sourceless operation
79
- filepath, ext = os.path.splitext(path)
92
+ ext = pathpath.suffix
80
93
  for ext in importlib.machinery.BYTECODE_SUFFIXES:
81
- if os.path.exists(filepath + ext):
82
- return filepath + ext
94
+ if pathpath.with_suffix(ext).exists():
95
+ return pathpath.with_suffix(ext)
83
96
  else:
84
97
  return None
85
98
 
86
99
 
87
- def load_python_file(dir_: str, filename: str) -> ModuleType:
100
+ def load_python_file(
101
+ dir_: Union[str, os.PathLike[str]], filename: Union[str, os.PathLike[str]]
102
+ ) -> ModuleType:
88
103
  """Load a file from the given path as a Python module."""
89
104
 
105
+ dir_ = pathlib.Path(dir_)
106
+ filename_as_path = pathlib.Path(filename)
107
+ filename = filename_as_path.name
108
+
90
109
  module_id = re.sub(r"\W", "_", filename)
91
- path = os.path.join(dir_, filename)
92
- _, ext = os.path.splitext(filename)
110
+ path = dir_ / filename
111
+ ext = path.suffix
93
112
  if ext == ".py":
94
- if os.path.exists(path):
113
+ if path.exists():
95
114
  module = load_module_py(module_id, path)
96
115
  else:
97
116
  pyc_path = pyc_file_from_path(path)
@@ -106,9 +125,27 @@ def load_python_file(dir_: str, filename: str) -> ModuleType:
106
125
  return module
107
126
 
108
127
 
109
- def load_module_py(module_id: str, path: str) -> ModuleType:
128
+ def load_module_py(
129
+ module_id: str, path: Union[str, os.PathLike[str]]
130
+ ) -> ModuleType:
110
131
  spec = importlib.util.spec_from_file_location(module_id, path)
111
132
  assert spec
112
133
  module = importlib.util.module_from_spec(spec)
113
134
  spec.loader.exec_module(module) # type: ignore
114
135
  return module
136
+
137
+
138
+ def _preserving_path_as_str(path: Union[str, os.PathLike[str]]) -> str:
139
+ """receive str/pathlike and return a string.
140
+
141
+ Does not convert an incoming string path to a Path first, to help with
142
+ unit tests that are doing string path round trips without OS-specific
143
+ processing if not necessary.
144
+
145
+ """
146
+ if isinstance(path, str):
147
+ return path
148
+ elif isinstance(path, pathlib.PurePath):
149
+ return str(path)
150
+ else:
151
+ return str(pathlib.Path(path))
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alembic
3
- Version: 1.15.2
3
+ Version: 1.16.1
4
4
  Summary: A database migration tool for SQLAlchemy.
5
5
  Author-email: Mike Bayer <mike_mp@zzzcomputing.com>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://alembic.sqlalchemy.org
8
8
  Project-URL: Documentation, https://alembic.sqlalchemy.org/en/latest/
9
9
  Project-URL: Changelog, https://alembic.sqlalchemy.org/en/latest/changelog.html
@@ -12,7 +12,6 @@ Project-URL: Issue Tracker, https://github.com/sqlalchemy/alembic/issues/
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Environment :: Console
15
- Classifier: License :: OSI Approved :: MIT License
16
15
  Classifier: Operating System :: OS Independent
17
16
  Classifier: Programming Language :: Python
18
17
  Classifier: Programming Language :: Python :: 3
@@ -30,6 +29,7 @@ License-File: LICENSE
30
29
  Requires-Dist: SQLAlchemy>=1.4.0
31
30
  Requires-Dist: Mako
32
31
  Requires-Dist: typing-extensions>=4.12
32
+ Requires-Dist: tomli; python_version < "3.11"
33
33
  Provides-Extra: tz
34
34
  Requires-Dist: tzdata; extra == "tz"
35
35
  Dynamic: license-file
@@ -1,57 +1,62 @@
1
- alembic/__init__.py,sha256=PDxLEkRWLmnGm-ZRbHkB5ttYSP5d2jSlESHuNdGYVtQ,63
1
+ alembic/__init__.py,sha256=dPYVgsjHZTtkz_8TPx47tDVuAPwMMa7aDa72Olb_rug,63
2
2
  alembic/__main__.py,sha256=373m7-TBh72JqrSMYviGrxCHZo-cnweM8AGF8A22PmY,78
3
- alembic/command.py,sha256=HIRFQFUG_A9ZgLBC-MG2WmE_eX0QxvvX2Os-_eL2zBQ,22242
4
- alembic/config.py,sha256=BZ7mwFRk2gq8GFNxxy9qvMUFx43YbDbQTC99OnjqiKY,22216
3
+ alembic/command.py,sha256=pZPQUGSxCjFu7qy0HMe02HJmByM0LOqoiK2AXKfRO3A,24855
4
+ alembic/config.py,sha256=KSvrY2rmIBpxZVswKH9ucNHFdxlxWcGXwYxtUdeppMo,32897
5
5
  alembic/context.py,sha256=hK1AJOQXJ29Bhn276GYcosxeG7pC5aZRT5E8c4bMJ4Q,195
6
6
  alembic/context.pyi,sha256=fdeFNTRc0bUgi7n2eZWVFh6NG-TzIv_0gAcapbfHnKY,31773
7
7
  alembic/environment.py,sha256=MM5lPayGT04H3aeng1H7GQ8HEAs3VGX5yy6mDLCPLT4,43
8
8
  alembic/migration.py,sha256=MV6Fju6rZtn2fTREKzXrCZM6aIBGII4OMZFix0X-GLs,41
9
9
  alembic/op.py,sha256=flHtcsVqOD-ZgZKK2pv-CJ5Cwh-KJ7puMUNXzishxLw,167
10
- alembic/op.pyi,sha256=_ZlgVwkkhey7kVGgnydFCLvvvFQo2uEofbyNpRXKupA,50180
10
+ alembic/op.pyi,sha256=PQ4mKNp7EXrjVdIWQRoGiBSVke4PPxTc9I6qF8ZGGZE,50711
11
11
  alembic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  alembic/autogenerate/__init__.py,sha256=ntmUTXhjLm4_zmqIwyVaECdpPDn6_u1yM9vYk6-553E,543
13
13
  alembic/autogenerate/api.py,sha256=L4qkapSJO1Ypymx8HsjLl0vFFt202agwMYsQbIe6ZtI,22219
14
- alembic/autogenerate/compare.py,sha256=FKmfogZOLXp4EIx9eQ-q_DzlnI4-jZYqyxw2yOw_84A,44341
15
- alembic/autogenerate/render.py,sha256=VFk0RZZ4Db_T2FQdtt2lzuHuE3x6r0VyWgzc_dnimgI,35877
14
+ alembic/autogenerate/compare.py,sha256=txW17LtHQkHzDdqf0MJ10fka0AbSt0qW2slu9QrcKLA,46021
15
+ alembic/autogenerate/render.py,sha256=tIcYsSeHoglueoBfsMtFh0WuBMu_EpvPWNPVDlUUlNI,36489
16
16
  alembic/autogenerate/rewriter.py,sha256=uZWRkTYJoncoEJ5WY1QBRiozjyChqZDJPy4LtcRibjM,7846
17
17
  alembic/ddl/__init__.py,sha256=Df8fy4Vn_abP8B7q3x8gyFwEwnLw6hs2Ljt_bV3EZWE,152
18
18
  alembic/ddl/_autogen.py,sha256=Blv2RrHNyF4cE6znCQXNXG5T9aO-YmiwD4Fz-qfoaWA,9275
19
- alembic/ddl/base.py,sha256=XlT5XEE6mtn09jfJ3khHmIM8iECmM8rlJEnTQa5vU60,9948
20
- alembic/ddl/impl.py,sha256=SYQg-Sz7OGOJi3h0VAC0GIEiJp7TZwUUN2VGshmj0uE,30066
21
- alembic/ddl/mssql.py,sha256=ydvgBSaftKYjaBaMyqius66Ta4CICQSj79Og3Ed2atY,14219
22
- alembic/ddl/mysql.py,sha256=9OOAmtg4GpEqWSbATT6FCq0xLnU8PMjr0VlRB171-EI,17301
19
+ alembic/ddl/base.py,sha256=A1f89-rCZvqw-hgWmBbIszRqx94lL6gKLFXE9kHettA,10478
20
+ alembic/ddl/impl.py,sha256=UL8-iza7CJk_T73lr5fjDLdhxEL56uD-AEjtmESAbLk,30439
21
+ alembic/ddl/mssql.py,sha256=NzORSIDHUll_g6iH4IyMTXZU1qjKzXrpespKrjWnfLY,14216
22
+ alembic/ddl/mysql.py,sha256=ujY4xDh13KgiFNRe3vUcLquie0ih80MYBUcogCBPdSc,17358
23
23
  alembic/ddl/oracle.py,sha256=669YlkcZihlXFbnXhH2krdrvDry8q5pcUGfoqkg_R6Y,6243
24
- alembic/ddl/postgresql.py,sha256=D4oCA2xCrKV-82aAEmXgEe-llyDtL4xc9_tAZgznkuU,29931
25
- alembic/ddl/sqlite.py,sha256=9p9dlXbGMZACqeFnSuhm7eSapFDGJNd6WhBhZrdpqFg,7995
24
+ alembic/ddl/postgresql.py,sha256=S7uye2NDSHLwV3w8SJ2Q9DLbcvQIxQfJ3EEK6JqyNag,29950
25
+ alembic/ddl/sqlite.py,sha256=u5tJgRUiY6bzVltl_NWlI6cy23v8XNagk_9gPI6Lnns,8006
26
26
  alembic/operations/__init__.py,sha256=e0KQSZAgLpTWvyvreB7DWg7RJV_MWSOPVDgCqsd2FzY,318
27
- alembic/operations/base.py,sha256=xG-pYE3Aw0kU0_7cxSiNpv_U9dSrWy4E5aOsAApOURs,74516
27
+ alembic/operations/base.py,sha256=npw1iFboTlEsaQS0b7mb2SEHsRDV4GLQqnjhcfma6Nk,75157
28
28
  alembic/operations/batch.py,sha256=1UmCFcsFWObinQWFRWoGZkjynl54HKpldbPs67aR4wg,26923
29
- alembic/operations/ops.py,sha256=Xjas55xKsOrT_BMLbiF_MpK2bhUMy1nCrI69--Gw1Bk,94983
29
+ alembic/operations/ops.py,sha256=ftsFgcZIctxRDiuGgkQsaFHsMlRP7cLq7Dj_seKVBnQ,96276
30
30
  alembic/operations/schemaobj.py,sha256=Wp-bBe4a8lXPTvIHJttBY0ejtpVR5Jvtb2kI-U2PztQ,9468
31
- alembic/operations/toimpl.py,sha256=DhydxHxPlPejzFPHsN1VR2tHINUdlJw3eKOjjmJCyu0,7114
31
+ alembic/operations/toimpl.py,sha256=rgufuSUNwpgrOYzzY3Q3ELW1rQv2fQbQVokXgnIYIrs,7503
32
32
  alembic/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  alembic/runtime/environment.py,sha256=W9Y_9tiecmYq885xqMZOrxZs80tN0M_ovXOdCLjGI5A,41524
34
34
  alembic/runtime/migration.py,sha256=X0O-sEuU54aNujyG_nxk1vs3BRBy2f-QwRJQmTucuVY,49874
35
35
  alembic/script/__init__.py,sha256=lSj06O391Iy5avWAiq8SPs6N8RBgxkSPjP8wpXcNDGg,100
36
- alembic/script/base.py,sha256=XLNpdsLnBBSz4ZKMFUArFUdtL1HcjtuUDHNbA-5VlZA,37809
37
- alembic/script/revision.py,sha256=NTu-eu5Y78u4NoVXpT0alpD2oL40SGATA2sEMEf1el4,62306
38
- alembic/script/write_hooks.py,sha256=NGB6NGgfdf7HK6XNNpSKqUCfzxazj-NRUePgFx7MJSM,5036
36
+ alembic/script/base.py,sha256=V-64yc3i3yZDVwSDd51NJKwTPUCdx4sqj3oog6nPq0A,36873
37
+ alembic/script/revision.py,sha256=BQcJoMCIXtSJRLCvdasgLOtCx9O7A8wsSym1FsqLW4s,62307
38
+ alembic/script/write_hooks.py,sha256=CAjh9U8m7eXz3W7pfQKVxG4UkHZrRIYKF6AkReakG2c,5015
39
39
  alembic/templates/async/README,sha256=ISVtAOvqvKk_5ThM5ioJE-lMkvf9IbknFUFVU_vPma4,58
40
- alembic/templates/async/alembic.ini.mako,sha256=mt-JvqniFqUGyVFBcB6dowg0bhQBTDDZfqEdGQJMJF4,3664
40
+ alembic/templates/async/alembic.ini.mako,sha256=ubJvGp-ai_C3RGJ_k5sedviIcIb2HIeExT1Y1K4X44o,4684
41
41
  alembic/templates/async/env.py,sha256=zbOCf3Y7w2lg92hxSwmG1MM_7y56i_oRH4AKp0pQBYo,2389
42
42
  alembic/templates/async/script.py.mako,sha256=3qBrHBf7F7ChKDUIdiNItiSXrDpgQdM7sR0YKzpaC50,689
43
43
  alembic/templates/generic/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
44
- alembic/templates/generic/alembic.ini.mako,sha256=5wBSGyn3C9RsfM3-ztwpHo2JPOnXT-6xwksyZ7nzPx0,3772
44
+ alembic/templates/generic/alembic.ini.mako,sha256=CqVaOZbWULb1NYjC6XTnLELPQ_TA9NPMOHKxJeG0vNY,4684
45
45
  alembic/templates/generic/env.py,sha256=TLRWOVW3Xpt_Tpf8JFzlnoPn_qoUu8UV77Y4o9XD6yI,2103
46
46
  alembic/templates/generic/script.py.mako,sha256=3qBrHBf7F7ChKDUIdiNItiSXrDpgQdM7sR0YKzpaC50,689
47
47
  alembic/templates/multidb/README,sha256=dWLDhnBgphA4Nzb7sNlMfCS3_06YqVbHhz-9O5JNqyI,606
48
- alembic/templates/multidb/alembic.ini.mako,sha256=10BzgDYUhrnMn4_hD1l-XH52TqlPEkQBlYs19zE3iyk,3866
48
+ alembic/templates/multidb/alembic.ini.mako,sha256=V-1FL7zyxHX1K_tBe_6Ax7DmGB_TevQvB77eIUfWvwk,5010
49
49
  alembic/templates/multidb/env.py,sha256=6zNjnW8mXGUk7erTsAvrfhvqoczJ-gagjVq1Ypg2YIQ,4230
50
50
  alembic/templates/multidb/script.py.mako,sha256=d0Pl1Z57DASni61GtdV1jTiSJfIx6IwIjEQx2_DeHIU,1220
51
- alembic/testing/__init__.py,sha256=kOxOh5nwmui9d-_CCq9WA4Udwy7ITjm453w74CTLZDo,1159
52
- alembic/testing/assertions.py,sha256=_zaiHj0RcmJs0u1EjrfELWUSi8aUu6xKvzdZ6hDuYUc,5196
53
- alembic/testing/env.py,sha256=IkQnQmp6g5U82iZHkcndr7MndO3_UBn2TF_40TZ2ua0,10537
54
- alembic/testing/fixtures.py,sha256=-0oudpWWZMGbwoeXSu1tlu5v8lLtl6eeKU8dMRUOWaU,9127
51
+ alembic/templates/pyproject/README,sha256=dMhIiFoeM7EdeaOXBs3mVQ6zXACMyGXDb_UBB6sGRA0,60
52
+ alembic/templates/pyproject/alembic.ini.mako,sha256=bQnEoydnLOUgg9vNbTOys4r5MaW8lmwYFXSrlfdEEkw,782
53
+ alembic/templates/pyproject/env.py,sha256=TLRWOVW3Xpt_Tpf8JFzlnoPn_qoUu8UV77Y4o9XD6yI,2103
54
+ alembic/templates/pyproject/pyproject.toml.mako,sha256=9CzBcdamN6ylIiJ-oGCaw__E84XbonVkNkuET3J7LKI,2645
55
+ alembic/templates/pyproject/script.py.mako,sha256=3qBrHBf7F7ChKDUIdiNItiSXrDpgQdM7sR0YKzpaC50,689
56
+ alembic/testing/__init__.py,sha256=JXvXAqIwFZB6-ep-BmeIqIH8xJ92XPt7DWCNkMDuJ-g,1249
57
+ alembic/testing/assertions.py,sha256=qcqf3tRAUe-A12NzuK_yxlksuX9OZKRC5E8pKIdBnPg,5302
58
+ alembic/testing/env.py,sha256=pka7fjwOC8hYL6X0XE4oPkJpy_1WX01bL7iP7gpO_4I,11551
59
+ alembic/testing/fixtures.py,sha256=fOzsRF8SW6CWpAH0sZpUHcgsJjun9EHnp4k2S3Lq5eU,9920
55
60
  alembic/testing/requirements.py,sha256=gNnnvgPCuiqKeHmiNymdQuYIjQ0BrxiPxu_in4eHEsc,4180
56
61
  alembic/testing/schemacompare.py,sha256=N5UqSNCOJetIKC4vKhpYzQEpj08XkdgIoqBmEPQ3tlc,4838
57
62
  alembic/testing/util.py,sha256=CQrcQDA8fs_7ME85z5ydb-Bt70soIIID-qNY1vbR2dg,3350
@@ -59,7 +64,7 @@ alembic/testing/warnings.py,sha256=cDDWzvxNZE6x9dME2ACTXSv01G81JcIbE1GIE_s1kvg,8
59
64
  alembic/testing/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
65
  alembic/testing/plugin/bootstrap.py,sha256=9C6wtjGrIVztZ928w27hsQE0KcjDLIUtUN3dvZKsMVk,50
61
66
  alembic/testing/suite/__init__.py,sha256=MvE7-hwbaVN1q3NM-ztGxORU9dnIelUCINKqNxewn7Y,288
62
- alembic/testing/suite/_autogen_fixtures.py,sha256=cDq1pmzHe15S6dZPGNC6sqFaCQ3hLT_oPV2IDigUGQ0,9880
67
+ alembic/testing/suite/_autogen_fixtures.py,sha256=Drrz_FKb9KDjq8hkwxtPkJVY1sCY7Biw-Muzb8kANp8,13480
63
68
  alembic/testing/suite/test_autogen_comments.py,sha256=aEGqKUDw4kHjnDk298aoGcQvXJWmZXcIX_2FxH4cJK8,6283
64
69
  alembic/testing/suite/test_autogen_computed.py,sha256=-5wran56qXo3afAbSk8cuSDDpbQweyJ61RF-GaVuZbA,4126
65
70
  alembic/testing/suite/test_autogen_diffs.py,sha256=T4SR1n_kmcOKYhR4W1-dA0e5sddJ69DSVL2HW96kAkE,8394
@@ -67,17 +72,17 @@ alembic/testing/suite/test_autogen_fks.py,sha256=AqFmb26Buex167HYa9dZWOk8x-JlB1O
67
72
  alembic/testing/suite/test_autogen_identity.py,sha256=kcuqngG7qXAKPJDX4U8sRzPKHEJECHuZ0DtuaS6tVkk,5824
68
73
  alembic/testing/suite/test_environment.py,sha256=OwD-kpESdLoc4byBrGrXbZHvqtPbzhFCG4W9hJOJXPQ,11877
69
74
  alembic/testing/suite/test_op.py,sha256=2XQCdm_NmnPxHGuGj7hmxMzIhKxXNotUsKdACXzE1mM,1343
70
- alembic/util/__init__.py,sha256=Afa20opZHVV6pH8HJDBOZpImPH9cWenrG-PaBnY_Xxc,1461
71
- alembic/util/compat.py,sha256=eoR9ReCTV_l0xGgGlr_OJmVvJecttBYXRKfDhoK8zKU,2630
75
+ alembic/util/__init__.py,sha256=_Zj_xp6ssKLyoLHUFzmKhnc8mhwXW8D8h7qyX-wO56M,1519
76
+ alembic/util/compat.py,sha256=Vt5xCn5Y675jI4seKNBV4IVnCl9V4wyH3OBI2w7U0EY,4248
72
77
  alembic/util/editor.py,sha256=JIz6_BdgV8_oKtnheR6DZoB7qnrHrlRgWjx09AsTsUw,2546
73
78
  alembic/util/exc.py,sha256=ZBlTQ8g-Jkb1iYFhFHs9djilRz0SSQ0Foc5SSoENs5o,564
74
79
  alembic/util/langhelpers.py,sha256=LpOcovnhMnP45kTt8zNJ4BHpyQrlF40OL6yDXjqKtsE,10026
75
- alembic/util/messaging.py,sha256=aLF6xbRiOCOEW1UY5vA9AAlfkGeNLqPPGSs-3c8-bfc,3166
76
- alembic/util/pyfiles.py,sha256=zltVdcwEJJCPS2gHsQvkHkQakuF6wXiZ6zfwHbGNT0g,3489
80
+ alembic/util/messaging.py,sha256=3bEBoDy4EAXETXAvArlYjeMITXDTgPTu6ZoE3ytnzSw,3294
81
+ alembic/util/pyfiles.py,sha256=ebkz9rQVPM3aMQ-_dtJ5ny4SFovCw4y6Ir1794Zu5C8,4609
77
82
  alembic/util/sqla_compat.py,sha256=SWAL4hJck4XLnUpe-oI3AGiH8w9kgDBe1_oakCfdT_Q,14785
78
- alembic-1.15.2.dist-info/licenses/LICENSE,sha256=NeqcNBmyYfrxvkSMT0fZJVKBv2s2tf_qVQUiJ9S6VN4,1059
79
- alembic-1.15.2.dist-info/METADATA,sha256=cVL7zyIqMo0m8XWloUHPxkUzUS9jiNq12BMZWm8igfo,7259
80
- alembic-1.15.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
81
- alembic-1.15.2.dist-info/entry_points.txt,sha256=aykM30soxwGN0pB7etLc1q0cHJbL9dy46RnK9VX4LLw,48
82
- alembic-1.15.2.dist-info/top_level.txt,sha256=FwKWd5VsPFC8iQjpu1u9Cn-JnK3-V1RhUCmWqz1cl-s,8
83
- alembic-1.15.2.dist-info/RECORD,,
83
+ alembic-1.16.1.dist-info/licenses/LICENSE,sha256=NeqcNBmyYfrxvkSMT0fZJVKBv2s2tf_qVQUiJ9S6VN4,1059
84
+ alembic-1.16.1.dist-info/METADATA,sha256=kgVKaGYM05A4pwv_3o1MEKjVVf8dQmJ76i-4A1mQzEw,7265
85
+ alembic-1.16.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
86
+ alembic-1.16.1.dist-info/entry_points.txt,sha256=aykM30soxwGN0pB7etLc1q0cHJbL9dy46RnK9VX4LLw,48
87
+ alembic-1.16.1.dist-info/top_level.txt,sha256=FwKWd5VsPFC8iQjpu1u9Cn-JnK3-V1RhUCmWqz1cl-s,8
88
+ alembic-1.16.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5