alembic 1.15.1__py3-none-any.whl → 1.16.0__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.
- alembic/__init__.py +1 -1
- alembic/autogenerate/compare.py +60 -7
- alembic/autogenerate/render.py +28 -4
- alembic/command.py +112 -37
- alembic/config.py +574 -222
- alembic/ddl/base.py +36 -8
- alembic/ddl/impl.py +24 -7
- alembic/ddl/mssql.py +3 -1
- alembic/ddl/mysql.py +8 -4
- alembic/ddl/postgresql.py +6 -2
- alembic/ddl/sqlite.py +1 -1
- alembic/op.pyi +25 -6
- alembic/operations/base.py +21 -4
- alembic/operations/ops.py +53 -10
- alembic/operations/toimpl.py +20 -3
- alembic/script/base.py +123 -136
- alembic/script/revision.py +1 -1
- alembic/script/write_hooks.py +20 -21
- alembic/templates/async/alembic.ini.mako +40 -16
- alembic/templates/generic/alembic.ini.mako +39 -17
- alembic/templates/multidb/alembic.ini.mako +42 -17
- alembic/templates/pyproject/README +1 -0
- alembic/templates/pyproject/alembic.ini.mako +44 -0
- alembic/templates/pyproject/env.py +78 -0
- alembic/templates/pyproject/pyproject.toml.mako +76 -0
- alembic/templates/pyproject/script.py.mako +28 -0
- alembic/testing/__init__.py +2 -0
- alembic/testing/assertions.py +4 -0
- alembic/testing/env.py +56 -1
- alembic/testing/fixtures.py +28 -1
- alembic/testing/suite/_autogen_fixtures.py +113 -0
- alembic/util/__init__.py +1 -0
- alembic/util/compat.py +56 -0
- alembic/util/messaging.py +4 -0
- alembic/util/pyfiles.py +56 -19
- {alembic-1.15.1.dist-info → alembic-1.16.0.dist-info}/METADATA +5 -4
- {alembic-1.15.1.dist-info → alembic-1.16.0.dist-info}/RECORD +41 -36
- {alembic-1.15.1.dist-info → alembic-1.16.0.dist-info}/WHEEL +1 -1
- {alembic-1.15.1.dist-info → alembic-1.16.0.dist-info}/entry_points.txt +0 -0
- {alembic-1.15.1.dist-info → alembic-1.16.0.dist-info/licenses}/LICENSE +0 -0
- {alembic-1.15.1.dist-info → alembic-1.16.0.dist-info}/top_level.txt +0 -0
alembic/ddl/base.py
CHANGED
@@ -154,17 +154,24 @@ class AddColumn(AlterTable):
|
|
154
154
|
name: str,
|
155
155
|
column: Column[Any],
|
156
156
|
schema: Optional[Union[quoted_name, str]] = None,
|
157
|
+
if_not_exists: Optional[bool] = None,
|
157
158
|
) -> None:
|
158
159
|
super().__init__(name, schema=schema)
|
159
160
|
self.column = column
|
161
|
+
self.if_not_exists = if_not_exists
|
160
162
|
|
161
163
|
|
162
164
|
class DropColumn(AlterTable):
|
163
165
|
def __init__(
|
164
|
-
self,
|
166
|
+
self,
|
167
|
+
name: str,
|
168
|
+
column: Column[Any],
|
169
|
+
schema: Optional[str] = None,
|
170
|
+
if_exists: Optional[bool] = None,
|
165
171
|
) -> None:
|
166
172
|
super().__init__(name, schema=schema)
|
167
173
|
self.column = column
|
174
|
+
self.if_exists = if_exists
|
168
175
|
|
169
176
|
|
170
177
|
class ColumnComment(AlterColumn):
|
@@ -189,7 +196,9 @@ def visit_rename_table(
|
|
189
196
|
def visit_add_column(element: AddColumn, compiler: DDLCompiler, **kw) -> str:
|
190
197
|
return "%s %s" % (
|
191
198
|
alter_table(compiler, element.table_name, element.schema),
|
192
|
-
add_column(
|
199
|
+
add_column(
|
200
|
+
compiler, element.column, if_not_exists=element.if_not_exists, **kw
|
201
|
+
),
|
193
202
|
)
|
194
203
|
|
195
204
|
|
@@ -197,7 +206,9 @@ def visit_add_column(element: AddColumn, compiler: DDLCompiler, **kw) -> str:
|
|
197
206
|
def visit_drop_column(element: DropColumn, compiler: DDLCompiler, **kw) -> str:
|
198
207
|
return "%s %s" % (
|
199
208
|
alter_table(compiler, element.table_name, element.schema),
|
200
|
-
drop_column(
|
209
|
+
drop_column(
|
210
|
+
compiler, element.column.name, if_exists=element.if_exists, **kw
|
211
|
+
),
|
201
212
|
)
|
202
213
|
|
203
214
|
|
@@ -299,9 +310,13 @@ def format_server_default(
|
|
299
310
|
compiler: DDLCompiler,
|
300
311
|
default: Optional[_ServerDefault],
|
301
312
|
) -> str:
|
302
|
-
|
313
|
+
# this can be updated to use compiler.render_default_string
|
314
|
+
# for SQLAlchemy 2.0 and above; not in 1.4
|
315
|
+
default_str = compiler.get_column_default_string(
|
303
316
|
Column("x", Integer, server_default=default)
|
304
317
|
)
|
318
|
+
assert default_str is not None
|
319
|
+
return default_str
|
305
320
|
|
306
321
|
|
307
322
|
def format_type(compiler: DDLCompiler, type_: TypeEngine) -> str:
|
@@ -316,16 +331,29 @@ def alter_table(
|
|
316
331
|
return "ALTER TABLE %s" % format_table_name(compiler, name, schema)
|
317
332
|
|
318
333
|
|
319
|
-
def drop_column(
|
320
|
-
|
334
|
+
def drop_column(
|
335
|
+
compiler: DDLCompiler, name: str, if_exists: Optional[bool] = None, **kw
|
336
|
+
) -> str:
|
337
|
+
return "DROP COLUMN %s%s" % (
|
338
|
+
"IF EXISTS " if if_exists else "",
|
339
|
+
format_column_name(compiler, name),
|
340
|
+
)
|
321
341
|
|
322
342
|
|
323
343
|
def alter_column(compiler: DDLCompiler, name: str) -> str:
|
324
344
|
return "ALTER COLUMN %s" % format_column_name(compiler, name)
|
325
345
|
|
326
346
|
|
327
|
-
def add_column(
|
328
|
-
|
347
|
+
def add_column(
|
348
|
+
compiler: DDLCompiler,
|
349
|
+
column: Column[Any],
|
350
|
+
if_not_exists: Optional[bool] = None,
|
351
|
+
**kw,
|
352
|
+
) -> str:
|
353
|
+
text = "ADD COLUMN %s%s" % (
|
354
|
+
"IF NOT EXISTS " if if_not_exists else "",
|
355
|
+
compiler.get_column_specification(column, **kw),
|
356
|
+
)
|
329
357
|
|
330
358
|
const = " ".join(
|
331
359
|
compiler.process(constraint) for constraint in column.constraints
|
alembic/ddl/impl.py
CHANGED
@@ -46,7 +46,6 @@ if TYPE_CHECKING:
|
|
46
46
|
from sqlalchemy.engine.reflection import Inspector
|
47
47
|
from sqlalchemy.sql import ClauseElement
|
48
48
|
from sqlalchemy.sql import Executable
|
49
|
-
from sqlalchemy.sql.elements import ColumnElement
|
50
49
|
from sqlalchemy.sql.elements import quoted_name
|
51
50
|
from sqlalchemy.sql.schema import Constraint
|
52
51
|
from sqlalchemy.sql.schema import ForeignKeyConstraint
|
@@ -257,8 +256,11 @@ class DefaultImpl(metaclass=ImplMeta):
|
|
257
256
|
self,
|
258
257
|
table_name: str,
|
259
258
|
column_name: str,
|
259
|
+
*,
|
260
260
|
nullable: Optional[bool] = None,
|
261
|
-
server_default:
|
261
|
+
server_default: Optional[
|
262
|
+
Union[_ServerDefault, Literal[False]]
|
263
|
+
] = False,
|
262
264
|
name: Optional[str] = None,
|
263
265
|
type_: Optional[TypeEngine] = None,
|
264
266
|
schema: Optional[str] = None,
|
@@ -369,25 +371,40 @@ class DefaultImpl(metaclass=ImplMeta):
|
|
369
371
|
self,
|
370
372
|
table_name: str,
|
371
373
|
column: Column[Any],
|
374
|
+
*,
|
372
375
|
schema: Optional[Union[str, quoted_name]] = None,
|
376
|
+
if_not_exists: Optional[bool] = None,
|
373
377
|
) -> None:
|
374
|
-
self._exec(
|
378
|
+
self._exec(
|
379
|
+
base.AddColumn(
|
380
|
+
table_name,
|
381
|
+
column,
|
382
|
+
schema=schema,
|
383
|
+
if_not_exists=if_not_exists,
|
384
|
+
)
|
385
|
+
)
|
375
386
|
|
376
387
|
def drop_column(
|
377
388
|
self,
|
378
389
|
table_name: str,
|
379
390
|
column: Column[Any],
|
391
|
+
*,
|
380
392
|
schema: Optional[str] = None,
|
393
|
+
if_exists: Optional[bool] = None,
|
381
394
|
**kw,
|
382
395
|
) -> None:
|
383
|
-
self._exec(
|
396
|
+
self._exec(
|
397
|
+
base.DropColumn(
|
398
|
+
table_name, column, schema=schema, if_exists=if_exists
|
399
|
+
)
|
400
|
+
)
|
384
401
|
|
385
402
|
def add_constraint(self, const: Any) -> None:
|
386
403
|
if const._create_rule is None or const._create_rule(self):
|
387
404
|
self._exec(schema.AddConstraint(const))
|
388
405
|
|
389
|
-
def drop_constraint(self, const: Constraint) -> None:
|
390
|
-
self._exec(schema.DropConstraint(const))
|
406
|
+
def drop_constraint(self, const: Constraint, **kw: Any) -> None:
|
407
|
+
self._exec(schema.DropConstraint(const, **kw))
|
391
408
|
|
392
409
|
def rename_table(
|
393
410
|
self,
|
@@ -440,7 +457,7 @@ class DefaultImpl(metaclass=ImplMeta):
|
|
440
457
|
def drop_table_comment(self, table: Table) -> None:
|
441
458
|
self._exec(schema.DropTableComment(table))
|
442
459
|
|
443
|
-
def create_column_comment(self, column:
|
460
|
+
def create_column_comment(self, column: Column[Any]) -> None:
|
444
461
|
self._exec(schema.SetColumnComment(column))
|
445
462
|
|
446
463
|
def drop_index(self, index: Index, **kw: Any) -> None:
|
alembic/ddl/mssql.py
CHANGED
@@ -83,10 +83,11 @@ class MSSQLImpl(DefaultImpl):
|
|
83
83
|
if self.as_sql and self.batch_separator:
|
84
84
|
self.static_output(self.batch_separator)
|
85
85
|
|
86
|
-
def alter_column(
|
86
|
+
def alter_column(
|
87
87
|
self,
|
88
88
|
table_name: str,
|
89
89
|
column_name: str,
|
90
|
+
*,
|
90
91
|
nullable: Optional[bool] = None,
|
91
92
|
server_default: Optional[
|
92
93
|
Union[_ServerDefault, Literal[False]]
|
@@ -202,6 +203,7 @@ class MSSQLImpl(DefaultImpl):
|
|
202
203
|
self,
|
203
204
|
table_name: str,
|
204
205
|
column: Column[Any],
|
206
|
+
*,
|
205
207
|
schema: Optional[str] = None,
|
206
208
|
**kw,
|
207
209
|
) -> None:
|
alembic/ddl/mysql.py
CHANGED
@@ -47,12 +47,15 @@ class MySQLImpl(DefaultImpl):
|
|
47
47
|
)
|
48
48
|
type_arg_extract = [r"character set ([\w\-_]+)", r"collate ([\w\-_]+)"]
|
49
49
|
|
50
|
-
def alter_column(
|
50
|
+
def alter_column(
|
51
51
|
self,
|
52
52
|
table_name: str,
|
53
53
|
column_name: str,
|
54
|
+
*,
|
54
55
|
nullable: Optional[bool] = None,
|
55
|
-
server_default:
|
56
|
+
server_default: Optional[
|
57
|
+
Union[_ServerDefault, Literal[False]]
|
58
|
+
] = False,
|
56
59
|
name: Optional[str] = None,
|
57
60
|
type_: Optional[TypeEngine] = None,
|
58
61
|
schema: Optional[str] = None,
|
@@ -165,6 +168,7 @@ class MySQLImpl(DefaultImpl):
|
|
165
168
|
def drop_constraint(
|
166
169
|
self,
|
167
170
|
const: Constraint,
|
171
|
+
**kw: Any,
|
168
172
|
) -> None:
|
169
173
|
if isinstance(const, schema.CheckConstraint) and _is_type_bound(const):
|
170
174
|
return
|
@@ -174,7 +178,7 @@ class MySQLImpl(DefaultImpl):
|
|
174
178
|
def _is_mysql_allowed_functional_default(
|
175
179
|
self,
|
176
180
|
type_: Optional[TypeEngine],
|
177
|
-
server_default: Union[_ServerDefault, Literal[False]],
|
181
|
+
server_default: Optional[Union[_ServerDefault, Literal[False]]],
|
178
182
|
) -> bool:
|
179
183
|
return (
|
180
184
|
type_ is not None
|
@@ -325,7 +329,7 @@ class MySQLAlterDefault(AlterColumn):
|
|
325
329
|
self,
|
326
330
|
name: str,
|
327
331
|
column_name: str,
|
328
|
-
default: _ServerDefault,
|
332
|
+
default: Optional[_ServerDefault],
|
329
333
|
schema: Optional[str] = None,
|
330
334
|
) -> None:
|
331
335
|
super(AlterColumn, self).__init__(name, schema=schema)
|
alembic/ddl/postgresql.py
CHANGED
@@ -52,6 +52,7 @@ from ..operations.base import Operations
|
|
52
52
|
from ..util import sqla_compat
|
53
53
|
from ..util.sqla_compat import compiles
|
54
54
|
|
55
|
+
|
55
56
|
if TYPE_CHECKING:
|
56
57
|
from typing import Literal
|
57
58
|
|
@@ -148,12 +149,15 @@ class PostgresqlImpl(DefaultImpl):
|
|
148
149
|
select(literal_column(conn_col_default) == metadata_default)
|
149
150
|
)
|
150
151
|
|
151
|
-
def alter_column(
|
152
|
+
def alter_column(
|
152
153
|
self,
|
153
154
|
table_name: str,
|
154
155
|
column_name: str,
|
156
|
+
*,
|
155
157
|
nullable: Optional[bool] = None,
|
156
|
-
server_default:
|
158
|
+
server_default: Optional[
|
159
|
+
Union[_ServerDefault, Literal[False]]
|
160
|
+
] = False,
|
157
161
|
name: Optional[str] = None,
|
158
162
|
type_: Optional[TypeEngine] = None,
|
159
163
|
schema: Optional[str] = None,
|
alembic/ddl/sqlite.py
CHANGED
@@ -91,7 +91,7 @@ class SQLiteImpl(DefaultImpl):
|
|
91
91
|
"SQLite migrations using a copy-and-move strategy."
|
92
92
|
)
|
93
93
|
|
94
|
-
def drop_constraint(self, const: Constraint):
|
94
|
+
def drop_constraint(self, const: Constraint, **kw: Any):
|
95
95
|
if const._create_rule is None:
|
96
96
|
raise NotImplementedError(
|
97
97
|
"No support for ALTER of constraints in SQLite dialect. "
|
alembic/op.pyi
CHANGED
@@ -60,7 +60,11 @@ _C = TypeVar("_C", bound=Callable[..., Any])
|
|
60
60
|
### end imports ###
|
61
61
|
|
62
62
|
def add_column(
|
63
|
-
table_name: str,
|
63
|
+
table_name: str,
|
64
|
+
column: Column[Any],
|
65
|
+
*,
|
66
|
+
schema: Optional[str] = None,
|
67
|
+
if_not_exists: Optional[bool] = None,
|
64
68
|
) -> None:
|
65
69
|
"""Issue an "add column" instruction using the current
|
66
70
|
migration context.
|
@@ -137,6 +141,10 @@ def add_column(
|
|
137
141
|
quoting of the schema outside of the default behavior, use
|
138
142
|
the SQLAlchemy construct
|
139
143
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
144
|
+
:param if_not_exists: If True, adds IF NOT EXISTS operator
|
145
|
+
when creating the new column for compatible dialects
|
146
|
+
|
147
|
+
.. versionadded:: 1.16.0
|
140
148
|
|
141
149
|
"""
|
142
150
|
|
@@ -146,12 +154,14 @@ def alter_column(
|
|
146
154
|
*,
|
147
155
|
nullable: Optional[bool] = None,
|
148
156
|
comment: Union[str, Literal[False], None] = False,
|
149
|
-
server_default:
|
157
|
+
server_default: Union[
|
158
|
+
str, bool, Identity, Computed, TextClause, None
|
159
|
+
] = False,
|
150
160
|
new_column_name: Optional[str] = None,
|
151
161
|
type_: Union[TypeEngine[Any], Type[TypeEngine[Any]], None] = None,
|
152
162
|
existing_type: Union[TypeEngine[Any], Type[TypeEngine[Any]], None] = None,
|
153
163
|
existing_server_default: Union[
|
154
|
-
str, bool, Identity, Computed, None
|
164
|
+
str, bool, Identity, Computed, TextClause, None
|
155
165
|
] = False,
|
156
166
|
existing_nullable: Optional[bool] = None,
|
157
167
|
existing_comment: Optional[str] = None,
|
@@ -925,6 +935,11 @@ def drop_column(
|
|
925
935
|
quoting of the schema outside of the default behavior, use
|
926
936
|
the SQLAlchemy construct
|
927
937
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
938
|
+
:param if_exists: If True, adds IF EXISTS operator when
|
939
|
+
dropping the new column for compatible dialects
|
940
|
+
|
941
|
+
.. versionadded:: 1.16.0
|
942
|
+
|
928
943
|
:param mssql_drop_check: Optional boolean. When ``True``, on
|
929
944
|
Microsoft SQL Server only, first
|
930
945
|
drop the CHECK constraint on the column using a
|
@@ -946,7 +961,6 @@ def drop_column(
|
|
946
961
|
then exec's a separate DROP CONSTRAINT for that default. Only
|
947
962
|
works if the column has exactly one FK constraint which refers to
|
948
963
|
it, at the moment.
|
949
|
-
|
950
964
|
"""
|
951
965
|
|
952
966
|
def drop_constraint(
|
@@ -955,6 +969,7 @@ def drop_constraint(
|
|
955
969
|
type_: Optional[str] = None,
|
956
970
|
*,
|
957
971
|
schema: Optional[str] = None,
|
972
|
+
if_exists: Optional[bool] = None,
|
958
973
|
) -> None:
|
959
974
|
r"""Drop a constraint of the given name, typically via DROP CONSTRAINT.
|
960
975
|
|
@@ -966,6 +981,10 @@ def drop_constraint(
|
|
966
981
|
quoting of the schema outside of the default behavior, use
|
967
982
|
the SQLAlchemy construct
|
968
983
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
984
|
+
:param if_exists: If True, adds IF EXISTS operator when
|
985
|
+
dropping the constraint
|
986
|
+
|
987
|
+
.. versionadded:: 1.16.0
|
969
988
|
|
970
989
|
"""
|
971
990
|
|
@@ -1165,7 +1184,7 @@ def f(name: str) -> conv:
|
|
1165
1184
|
names will be converted along conventions. If the ``target_metadata``
|
1166
1185
|
contains the naming convention
|
1167
1186
|
``{"ck": "ck_bool_%(table_name)s_%(constraint_name)s"}``, then the
|
1168
|
-
output of the following
|
1187
|
+
output of the following::
|
1169
1188
|
|
1170
1189
|
op.add_column("t", "x", Boolean(name="x"))
|
1171
1190
|
|
@@ -1269,7 +1288,7 @@ def invoke(
|
|
1269
1288
|
BulkInsertOp,
|
1270
1289
|
DropTableOp,
|
1271
1290
|
ExecuteSQLOp,
|
1272
|
-
]
|
1291
|
+
],
|
1273
1292
|
) -> None: ...
|
1274
1293
|
@overload
|
1275
1294
|
def invoke(operation: MigrateOperation) -> Any:
|
alembic/operations/base.py
CHANGED
@@ -464,7 +464,7 @@ class AbstractOperations(util.ModuleClsProxy):
|
|
464
464
|
names will be converted along conventions. If the ``target_metadata``
|
465
465
|
contains the naming convention
|
466
466
|
``{"ck": "ck_bool_%(table_name)s_%(constraint_name)s"}``, then the
|
467
|
-
output of the following
|
467
|
+
output of the following::
|
468
468
|
|
469
469
|
op.add_column("t", "x", Boolean(name="x"))
|
470
470
|
|
@@ -618,6 +618,7 @@ class Operations(AbstractOperations):
|
|
618
618
|
column: Column[Any],
|
619
619
|
*,
|
620
620
|
schema: Optional[str] = None,
|
621
|
+
if_not_exists: Optional[bool] = None,
|
621
622
|
) -> None:
|
622
623
|
"""Issue an "add column" instruction using the current
|
623
624
|
migration context.
|
@@ -694,6 +695,10 @@ class Operations(AbstractOperations):
|
|
694
695
|
quoting of the schema outside of the default behavior, use
|
695
696
|
the SQLAlchemy construct
|
696
697
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
698
|
+
:param if_not_exists: If True, adds IF NOT EXISTS operator
|
699
|
+
when creating the new column for compatible dialects
|
700
|
+
|
701
|
+
.. versionadded:: 1.16.0
|
697
702
|
|
698
703
|
""" # noqa: E501
|
699
704
|
...
|
@@ -705,14 +710,16 @@ class Operations(AbstractOperations):
|
|
705
710
|
*,
|
706
711
|
nullable: Optional[bool] = None,
|
707
712
|
comment: Union[str, Literal[False], None] = False,
|
708
|
-
server_default:
|
713
|
+
server_default: Union[
|
714
|
+
str, bool, Identity, Computed, TextClause, None
|
715
|
+
] = False,
|
709
716
|
new_column_name: Optional[str] = None,
|
710
717
|
type_: Union[TypeEngine[Any], Type[TypeEngine[Any]], None] = None,
|
711
718
|
existing_type: Union[
|
712
719
|
TypeEngine[Any], Type[TypeEngine[Any]], None
|
713
720
|
] = None,
|
714
721
|
existing_server_default: Union[
|
715
|
-
str, bool, Identity, Computed, None
|
722
|
+
str, bool, Identity, Computed, TextClause, None
|
716
723
|
] = False,
|
717
724
|
existing_nullable: Optional[bool] = None,
|
718
725
|
existing_comment: Optional[str] = None,
|
@@ -1359,6 +1366,11 @@ class Operations(AbstractOperations):
|
|
1359
1366
|
quoting of the schema outside of the default behavior, use
|
1360
1367
|
the SQLAlchemy construct
|
1361
1368
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
1369
|
+
:param if_exists: If True, adds IF EXISTS operator when
|
1370
|
+
dropping the new column for compatible dialects
|
1371
|
+
|
1372
|
+
.. versionadded:: 1.16.0
|
1373
|
+
|
1362
1374
|
:param mssql_drop_check: Optional boolean. When ``True``, on
|
1363
1375
|
Microsoft SQL Server only, first
|
1364
1376
|
drop the CHECK constraint on the column using a
|
@@ -1380,7 +1392,6 @@ class Operations(AbstractOperations):
|
|
1380
1392
|
then exec's a separate DROP CONSTRAINT for that default. Only
|
1381
1393
|
works if the column has exactly one FK constraint which refers to
|
1382
1394
|
it, at the moment.
|
1383
|
-
|
1384
1395
|
""" # noqa: E501
|
1385
1396
|
...
|
1386
1397
|
|
@@ -1391,6 +1402,7 @@ class Operations(AbstractOperations):
|
|
1391
1402
|
type_: Optional[str] = None,
|
1392
1403
|
*,
|
1393
1404
|
schema: Optional[str] = None,
|
1405
|
+
if_exists: Optional[bool] = None,
|
1394
1406
|
) -> None:
|
1395
1407
|
r"""Drop a constraint of the given name, typically via DROP CONSTRAINT.
|
1396
1408
|
|
@@ -1402,6 +1414,10 @@ class Operations(AbstractOperations):
|
|
1402
1414
|
quoting of the schema outside of the default behavior, use
|
1403
1415
|
the SQLAlchemy construct
|
1404
1416
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
1417
|
+
:param if_exists: If True, adds IF EXISTS operator when
|
1418
|
+
dropping the constraint
|
1419
|
+
|
1420
|
+
.. versionadded:: 1.16.0
|
1405
1421
|
|
1406
1422
|
""" # noqa: E501
|
1407
1423
|
...
|
@@ -1644,6 +1660,7 @@ class BatchOperations(AbstractOperations):
|
|
1644
1660
|
*,
|
1645
1661
|
insert_before: Optional[str] = None,
|
1646
1662
|
insert_after: Optional[str] = None,
|
1663
|
+
if_not_exists: Optional[bool] = None,
|
1647
1664
|
) -> None:
|
1648
1665
|
"""Issue an "add column" instruction using the current
|
1649
1666
|
batch migration context.
|
alembic/operations/ops.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from abc import abstractmethod
|
4
|
+
import os
|
5
|
+
import pathlib
|
4
6
|
import re
|
5
7
|
from typing import Any
|
6
8
|
from typing import Callable
|
@@ -140,12 +142,14 @@ class DropConstraintOp(MigrateOperation):
|
|
140
142
|
type_: Optional[str] = None,
|
141
143
|
*,
|
142
144
|
schema: Optional[str] = None,
|
145
|
+
if_exists: Optional[bool] = None,
|
143
146
|
_reverse: Optional[AddConstraintOp] = None,
|
144
147
|
) -> None:
|
145
148
|
self.constraint_name = constraint_name
|
146
149
|
self.table_name = table_name
|
147
150
|
self.constraint_type = type_
|
148
151
|
self.schema = schema
|
152
|
+
self.if_exists = if_exists
|
149
153
|
self._reverse = _reverse
|
150
154
|
|
151
155
|
def reverse(self) -> AddConstraintOp:
|
@@ -203,6 +207,7 @@ class DropConstraintOp(MigrateOperation):
|
|
203
207
|
type_: Optional[str] = None,
|
204
208
|
*,
|
205
209
|
schema: Optional[str] = None,
|
210
|
+
if_exists: Optional[bool] = None,
|
206
211
|
) -> None:
|
207
212
|
r"""Drop a constraint of the given name, typically via DROP CONSTRAINT.
|
208
213
|
|
@@ -214,10 +219,20 @@ class DropConstraintOp(MigrateOperation):
|
|
214
219
|
quoting of the schema outside of the default behavior, use
|
215
220
|
the SQLAlchemy construct
|
216
221
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
222
|
+
:param if_exists: If True, adds IF EXISTS operator when
|
223
|
+
dropping the constraint
|
224
|
+
|
225
|
+
.. versionadded:: 1.16.0
|
217
226
|
|
218
227
|
"""
|
219
228
|
|
220
|
-
op = cls(
|
229
|
+
op = cls(
|
230
|
+
constraint_name,
|
231
|
+
table_name,
|
232
|
+
type_=type_,
|
233
|
+
schema=schema,
|
234
|
+
if_exists=if_exists,
|
235
|
+
)
|
221
236
|
return operations.invoke(op)
|
222
237
|
|
223
238
|
@classmethod
|
@@ -1840,14 +1855,16 @@ class AlterColumnOp(AlterTableOp):
|
|
1840
1855
|
*,
|
1841
1856
|
nullable: Optional[bool] = None,
|
1842
1857
|
comment: Optional[Union[str, Literal[False]]] = False,
|
1843
|
-
server_default:
|
1858
|
+
server_default: Union[
|
1859
|
+
str, bool, Identity, Computed, TextClause, None
|
1860
|
+
] = False,
|
1844
1861
|
new_column_name: Optional[str] = None,
|
1845
1862
|
type_: Optional[Union[TypeEngine[Any], Type[TypeEngine[Any]]]] = None,
|
1846
1863
|
existing_type: Optional[
|
1847
1864
|
Union[TypeEngine[Any], Type[TypeEngine[Any]]]
|
1848
1865
|
] = None,
|
1849
|
-
existing_server_default:
|
1850
|
-
|
1866
|
+
existing_server_default: Union[
|
1867
|
+
str, bool, Identity, Computed, TextClause, None
|
1851
1868
|
] = False,
|
1852
1869
|
existing_nullable: Optional[bool] = None,
|
1853
1870
|
existing_comment: Optional[str] = None,
|
@@ -2032,16 +2049,20 @@ class AddColumnOp(AlterTableOp):
|
|
2032
2049
|
column: Column[Any],
|
2033
2050
|
*,
|
2034
2051
|
schema: Optional[str] = None,
|
2052
|
+
if_not_exists: Optional[bool] = None,
|
2035
2053
|
**kw: Any,
|
2036
2054
|
) -> None:
|
2037
2055
|
super().__init__(table_name, schema=schema)
|
2038
2056
|
self.column = column
|
2057
|
+
self.if_not_exists = if_not_exists
|
2039
2058
|
self.kw = kw
|
2040
2059
|
|
2041
2060
|
def reverse(self) -> DropColumnOp:
|
2042
|
-
|
2061
|
+
op = DropColumnOp.from_column_and_tablename(
|
2043
2062
|
self.schema, self.table_name, self.column
|
2044
2063
|
)
|
2064
|
+
op.if_exists = self.if_not_exists
|
2065
|
+
return op
|
2045
2066
|
|
2046
2067
|
def to_diff_tuple(
|
2047
2068
|
self,
|
@@ -2072,6 +2093,7 @@ class AddColumnOp(AlterTableOp):
|
|
2072
2093
|
column: Column[Any],
|
2073
2094
|
*,
|
2074
2095
|
schema: Optional[str] = None,
|
2096
|
+
if_not_exists: Optional[bool] = None,
|
2075
2097
|
) -> None:
|
2076
2098
|
"""Issue an "add column" instruction using the current
|
2077
2099
|
migration context.
|
@@ -2148,10 +2170,19 @@ class AddColumnOp(AlterTableOp):
|
|
2148
2170
|
quoting of the schema outside of the default behavior, use
|
2149
2171
|
the SQLAlchemy construct
|
2150
2172
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
2173
|
+
:param if_not_exists: If True, adds IF NOT EXISTS operator
|
2174
|
+
when creating the new column for compatible dialects
|
2175
|
+
|
2176
|
+
.. versionadded:: 1.16.0
|
2151
2177
|
|
2152
2178
|
"""
|
2153
2179
|
|
2154
|
-
op = cls(
|
2180
|
+
op = cls(
|
2181
|
+
table_name,
|
2182
|
+
column,
|
2183
|
+
schema=schema,
|
2184
|
+
if_not_exists=if_not_exists,
|
2185
|
+
)
|
2155
2186
|
return operations.invoke(op)
|
2156
2187
|
|
2157
2188
|
@classmethod
|
@@ -2162,6 +2193,7 @@ class AddColumnOp(AlterTableOp):
|
|
2162
2193
|
*,
|
2163
2194
|
insert_before: Optional[str] = None,
|
2164
2195
|
insert_after: Optional[str] = None,
|
2196
|
+
if_not_exists: Optional[bool] = None,
|
2165
2197
|
) -> None:
|
2166
2198
|
"""Issue an "add column" instruction using the current
|
2167
2199
|
batch migration context.
|
@@ -2182,6 +2214,7 @@ class AddColumnOp(AlterTableOp):
|
|
2182
2214
|
operations.impl.table_name,
|
2183
2215
|
column,
|
2184
2216
|
schema=operations.impl.schema,
|
2217
|
+
if_not_exists=if_not_exists,
|
2185
2218
|
**kw,
|
2186
2219
|
)
|
2187
2220
|
return operations.invoke(op)
|
@@ -2198,12 +2231,14 @@ class DropColumnOp(AlterTableOp):
|
|
2198
2231
|
column_name: str,
|
2199
2232
|
*,
|
2200
2233
|
schema: Optional[str] = None,
|
2234
|
+
if_exists: Optional[bool] = None,
|
2201
2235
|
_reverse: Optional[AddColumnOp] = None,
|
2202
2236
|
**kw: Any,
|
2203
2237
|
) -> None:
|
2204
2238
|
super().__init__(table_name, schema=schema)
|
2205
2239
|
self.column_name = column_name
|
2206
2240
|
self.kw = kw
|
2241
|
+
self.if_exists = if_exists
|
2207
2242
|
self._reverse = _reverse
|
2208
2243
|
|
2209
2244
|
def to_diff_tuple(
|
@@ -2223,9 +2258,11 @@ class DropColumnOp(AlterTableOp):
|
|
2223
2258
|
"original column is not present"
|
2224
2259
|
)
|
2225
2260
|
|
2226
|
-
|
2261
|
+
op = AddColumnOp.from_column_and_tablename(
|
2227
2262
|
self.schema, self.table_name, self._reverse.column
|
2228
2263
|
)
|
2264
|
+
op.if_not_exists = self.if_exists
|
2265
|
+
return op
|
2229
2266
|
|
2230
2267
|
@classmethod
|
2231
2268
|
def from_column_and_tablename(
|
@@ -2272,6 +2309,11 @@ class DropColumnOp(AlterTableOp):
|
|
2272
2309
|
quoting of the schema outside of the default behavior, use
|
2273
2310
|
the SQLAlchemy construct
|
2274
2311
|
:class:`~sqlalchemy.sql.elements.quoted_name`.
|
2312
|
+
:param if_exists: If True, adds IF EXISTS operator when
|
2313
|
+
dropping the new column for compatible dialects
|
2314
|
+
|
2315
|
+
.. versionadded:: 1.16.0
|
2316
|
+
|
2275
2317
|
:param mssql_drop_check: Optional boolean. When ``True``, on
|
2276
2318
|
Microsoft SQL Server only, first
|
2277
2319
|
drop the CHECK constraint on the column using a
|
@@ -2293,7 +2335,6 @@ class DropColumnOp(AlterTableOp):
|
|
2293
2335
|
then exec's a separate DROP CONSTRAINT for that default. Only
|
2294
2336
|
works if the column has exactly one FK constraint which refers to
|
2295
2337
|
it, at the moment.
|
2296
|
-
|
2297
2338
|
"""
|
2298
2339
|
|
2299
2340
|
op = cls(table_name, column_name, schema=schema, **kw)
|
@@ -2708,7 +2749,7 @@ class MigrationScript(MigrateOperation):
|
|
2708
2749
|
head: Optional[str] = None,
|
2709
2750
|
splice: Optional[bool] = None,
|
2710
2751
|
branch_label: Optional[_RevIdType] = None,
|
2711
|
-
version_path:
|
2752
|
+
version_path: Union[str, os.PathLike[str], None] = None,
|
2712
2753
|
depends_on: Optional[_RevIdType] = None,
|
2713
2754
|
) -> None:
|
2714
2755
|
self.rev_id = rev_id
|
@@ -2717,7 +2758,9 @@ class MigrationScript(MigrateOperation):
|
|
2717
2758
|
self.head = head
|
2718
2759
|
self.splice = splice
|
2719
2760
|
self.branch_label = branch_label
|
2720
|
-
self.version_path =
|
2761
|
+
self.version_path = (
|
2762
|
+
pathlib.Path(version_path).as_posix() if version_path else None
|
2763
|
+
)
|
2721
2764
|
self.depends_on = depends_on
|
2722
2765
|
self.upgrade_ops = upgrade_ops
|
2723
2766
|
self.downgrade_ops = downgrade_ops
|