Skip to content

Commit ab446ab

Browse files
committed
drop SQLAlchemy 1.3, Python 3.8
Jenkins issues reveal that SQLAlchemy 1.3's testing provision has unidentified deficiencies that are causing instability with the mssql engine. As provisioning was highly refactored in 1.4, just drop 1.3 support rather than trying to figure out the exact thing that changed. Support for SQLAlchemy 1.3, which was EOL as of 2021, is now dropped from Alembic as of version 1.15.0. Support for Python 3.8 is dropped as of Alembic 1.15.0. Python 3.8 is EOL. Try pytest 8.3 as this seems to be running fine for SQLAlchemy Change-Id: I06614a6f73d5b1a1ac5b9b04225ecb305f5b35ee
1 parent d881db0 commit ab446ab

37 files changed

+269
-678
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ coverage.xml
2222
/docs/build/_build/
2323
/pysqlite_test_schema.db
2424
*.sqlite3
25+
.mypy_cache/

alembic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from . import context
22
from . import op
33

4-
__version__ = "1.14.2"
4+
__version__ = "1.15.0"

alembic/autogenerate/compare.py

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def _compare_tables(
216216
(inspector),
217217
# fmt: on
218218
)
219-
sqla_compat._reflect_table(inspector, t)
219+
inspector.reflect_table(t, include_columns=None)
220220
if autogen_context.run_object_filters(t, tname, "table", True, None):
221221
modify_table_ops = ops.ModifyTableOps(tname, [], schema=s)
222222

@@ -246,7 +246,7 @@ def _compare_tables(
246246
_compat_autogen_column_reflect(inspector),
247247
# fmt: on
248248
)
249-
sqla_compat._reflect_table(inspector, t)
249+
inspector.reflect_table(t, include_columns=None)
250250
conn_column_info[(s, tname)] = t
251251

252252
for s, tname in sorted(existing_tables, key=lambda x: (x[0] or "", x[1])):
@@ -1067,27 +1067,15 @@ def _compare_server_default(
10671067
return False
10681068

10691069
if sqla_compat._server_default_is_computed(metadata_default):
1070-
# return False in case of a computed column as the server
1071-
# default. Note that DDL for adding or removing "GENERATED AS" from
1072-
# an existing column is not currently known for any backend.
1073-
# Once SQLAlchemy can reflect "GENERATED" as the "computed" element,
1074-
# we would also want to ignore and/or warn for changes vs. the
1075-
# metadata (or support backend specific DDL if applicable).
1076-
if not sqla_compat.has_computed_reflection:
1077-
return False
1078-
1079-
else:
1080-
return (
1081-
_compare_computed_default( # type:ignore[func-returns-value]
1082-
autogen_context,
1083-
alter_column_op,
1084-
schema,
1085-
tname,
1086-
cname,
1087-
conn_col,
1088-
metadata_col,
1089-
)
1090-
)
1070+
return _compare_computed_default( # type:ignore[func-returns-value]
1071+
autogen_context,
1072+
alter_column_op,
1073+
schema,
1074+
tname,
1075+
cname,
1076+
conn_col,
1077+
metadata_col,
1078+
)
10911079
if sqla_compat._server_default_is_computed(conn_col_default):
10921080
_warn_computed_not_supported(tname, cname)
10931081
return False

alembic/autogenerate/render.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
if TYPE_CHECKING:
2929
from typing import Literal
3030

31+
from sqlalchemy import Computed
32+
from sqlalchemy import Identity
3133
from sqlalchemy.sql.base import DialectKWArgs
3234
from sqlalchemy.sql.elements import ColumnElement
3335
from sqlalchemy.sql.elements import TextClause
@@ -48,8 +50,6 @@
4850
from alembic.config import Config
4951
from alembic.operations.ops import MigrationScript
5052
from alembic.operations.ops import ModifyTableOps
51-
from alembic.util.sqla_compat import Computed
52-
from alembic.util.sqla_compat import Identity
5353

5454

5555
MAX_PYTHON_ARGS = 255
@@ -741,7 +741,7 @@ def _render_column(
741741
+ [
742742
"%s=%s"
743743
% (key, _render_potential_expr(val, autogen_context))
744-
for key, val in sqla_compat._column_kwargs(column).items()
744+
for key, val in column.kwargs.items()
745745
]
746746
)
747747
),

alembic/ddl/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
if TYPE_CHECKING:
2626
from typing import Any
2727

28+
from sqlalchemy import Computed
29+
from sqlalchemy import Identity
2830
from sqlalchemy.sql.compiler import Compiled
2931
from sqlalchemy.sql.compiler import DDLCompiler
3032
from sqlalchemy.sql.elements import TextClause
@@ -33,8 +35,6 @@
3335
from sqlalchemy.sql.type_api import TypeEngine
3436

3537
from .impl import DefaultImpl
36-
from ..util.sqla_compat import Computed
37-
from ..util.sqla_compat import Identity
3838

3939
_ServerDefault = Union["TextClause", "FetchedValue", "Function[Any]", str]
4040

alembic/ddl/impl.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,9 @@ def bulk_insert(
459459
if self.as_sql:
460460
for row in rows:
461461
self._exec(
462-
sqla_compat._insert_inline(table).values(
462+
table.insert()
463+
.inline()
464+
.values(
463465
**{
464466
k: (
465467
sqla_compat._literal_bindparam(
@@ -477,14 +479,10 @@ def bulk_insert(
477479
else:
478480
if rows:
479481
if multiinsert:
480-
self._exec(
481-
sqla_compat._insert_inline(table), multiparams=rows
482-
)
482+
self._exec(table.insert().inline(), multiparams=rows)
483483
else:
484484
for row in rows:
485-
self._exec(
486-
sqla_compat._insert_inline(table).values(**row)
487-
)
485+
self._exec(table.insert().inline().values(**row))
488486

489487
def _tokenize_column_type(self, column: Column) -> Params:
490488
definition: str
@@ -693,7 +691,7 @@ def _compare_identity_default(self, metadata_identity, inspector_identity):
693691
diff, ignored = _compare_identity_options(
694692
metadata_identity,
695693
inspector_identity,
696-
sqla_compat.Identity(),
694+
schema.Identity(),
697695
skip={"always"},
698696
)
699697

@@ -874,12 +872,13 @@ def check_dicts(
874872
set(meta_d).union(insp_d),
875873
)
876874
if sqla_compat.identity_has_dialect_kwargs:
875+
assert hasattr(default_io, "dialect_kwargs")
877876
# use only the dialect kwargs in inspector_io since metadata_io
878877
# can have options for many backends
879878
check_dicts(
880879
getattr(metadata_io, "dialect_kwargs", {}),
881880
getattr(inspector_io, "dialect_kwargs", {}),
882-
default_io.dialect_kwargs, # type: ignore[union-attr]
881+
default_io.dialect_kwargs,
883882
getattr(inspector_io, "dialect_kwargs", {}),
884883
)
885884

alembic/ddl/mysql.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from .impl import DefaultImpl
2424
from .. import util
2525
from ..util import sqla_compat
26-
from ..util.sqla_compat import _is_mariadb
2726
from ..util.sqla_compat import _is_type_bound
2827
from ..util.sqla_compat import compiles
2928

@@ -475,7 +474,7 @@ def _mysql_drop_constraint(
475474
# note that SQLAlchemy as of 1.2 does not yet support
476475
# DROP CONSTRAINT for MySQL/MariaDB, so we implement fully
477476
# here.
478-
if _is_mariadb(compiler.dialect):
477+
if compiler.dialect.is_mariadb: # type: ignore[attr-defined]
479478
return "ALTER TABLE %s DROP CONSTRAINT %s" % (
480479
compiler.preparer.format_table(constraint.table),
481480
compiler.preparer.format_constraint(constraint),

alembic/ddl/postgresql.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818
from sqlalchemy import Column
1919
from sqlalchemy import Float
20+
from sqlalchemy import Identity
2021
from sqlalchemy import literal_column
2122
from sqlalchemy import Numeric
23+
from sqlalchemy import select
2224
from sqlalchemy import text
2325
from sqlalchemy import types as sqltypes
2426
from sqlalchemy.dialects.postgresql import BIGINT
@@ -143,9 +145,7 @@ def compare_server_default(
143145
conn = self.connection
144146
assert conn is not None
145147
return not conn.scalar(
146-
sqla_compat._select(
147-
literal_column(conn_col_default) == metadata_default
148-
)
148+
select(literal_column(conn_col_default) == metadata_default)
149149
)
150150

151151
def alter_column( # type:ignore[override]
@@ -586,7 +586,7 @@ def visit_identity_column(
586586
)
587587
else:
588588
text += "SET %s " % compiler.get_identity_options(
589-
sqla_compat.Identity(**{attr: getattr(identity, attr)})
589+
Identity(**{attr: getattr(identity, attr)})
590590
)
591591
return text
592592

alembic/ddl/sqlite.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from typing import Union
1212

1313
from sqlalchemy import cast
14+
from sqlalchemy import Computed
1415
from sqlalchemy import JSON
1516
from sqlalchemy import schema
1617
from sqlalchemy import sql
@@ -64,7 +65,7 @@ def requires_recreate_in_batch(
6465
) and isinstance(col.server_default.arg, sql.ClauseElement):
6566
return True
6667
elif (
67-
isinstance(col.server_default, util.sqla_compat.Computed)
68+
isinstance(col.server_default, Computed)
6869
and col.server_default.persisted
6970
):
7071
return True

alembic/operations/batch.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from sqlalchemy import MetaData
1919
from sqlalchemy import PrimaryKeyConstraint
2020
from sqlalchemy import schema as sql_schema
21+
from sqlalchemy import select
2122
from sqlalchemy import Table
2223
from sqlalchemy import types as sqltypes
2324
from sqlalchemy.sql.schema import SchemaEventTarget
@@ -31,11 +32,9 @@
3132
from ..util.sqla_compat import _ensure_scope_for_ddl
3233
from ..util.sqla_compat import _fk_is_self_referential
3334
from ..util.sqla_compat import _idx_table_bound_expressions
34-
from ..util.sqla_compat import _insert_inline
3535
from ..util.sqla_compat import _is_type_bound
3636
from ..util.sqla_compat import _remove_column_from_collection
3737
from ..util.sqla_compat import _resolve_for_variant
38-
from ..util.sqla_compat import _select
3938
from ..util.sqla_compat import constraint_name_defined
4039
from ..util.sqla_compat import constraint_name_string
4140

@@ -449,13 +448,15 @@ def _create(self, op_impl: DefaultImpl) -> None:
449448

450449
try:
451450
op_impl._exec(
452-
_insert_inline(self.new_table).from_select(
451+
self.new_table.insert()
452+
.inline()
453+
.from_select(
453454
list(
454455
k
455456
for k, transfer in self.column_transfers.items()
456457
if "expr" in transfer
457458
),
458-
_select(
459+
select(
459460
*[
460461
transfer["expr"]
461462
for transfer in self.column_transfers.values()

0 commit comments

Comments
 (0)