ferrum-orm 0.1.21__tar.gz → 0.1.22__tar.gz
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.
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/Cargo.lock +4 -4
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/Cargo.toml +1 -1
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/PKG-INFO +6 -1
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/README.md +5 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/pyproject.toml +1 -1
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/__init__.py +1 -1
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/makemigrations_cmd.py +6 -1
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/orchestrator.py +61 -15
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/LICENSE +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/Cargo.toml +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/benches/hydrate.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/src/compile/mod.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/src/error.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/src/hydrate/mod.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/src/ir/metadata.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/src/ir/mod.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/src/lib.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-core/src/migrate/mod.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-pyo3/Cargo.toml +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-pyo3/src/lib.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/Cargo.toml +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/benches/compile.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/dialect.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/emit.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/fts/mod.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/fts/mssql.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/fts/mysql.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/fts/postgres.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/fts/sqlite.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/crates/ferrum-sql/src/lib.rs +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/_native.pyi +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/__init__.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/app.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/bootstrap.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/check_schema_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/init.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/inspectdb_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/migrate_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/migrations_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/resetdb_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/revert_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/showmigrations_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/cli/sqlmigrate_cmd.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/config.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/connection.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/contrib/__init__.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/contrib/fastapi.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/drivers/__init__.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/drivers/mssql.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/drivers/mysql.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/drivers/postgres.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/drivers/protocol.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/drivers/sqlite.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/drivers/streaming.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/echo.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/errors.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/expressions.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/ext/__init__.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/ext/fts.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/ext/pgvector.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/hooks.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/__init__.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/autodiff.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/base.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/coordinator.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/drift.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/fts/__init__.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/fts/mssql.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/fts/mysql.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/fts/postgres.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/fts/sqlite.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/gates.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/introspect.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/ledger.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/loader.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/operations.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/migrations/tokens.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/models.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/observability.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/py.typed +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/queryset.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/registry.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/relations.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/routing.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/runtime.py +0 -0
- {ferrum_orm-0.1.21 → ferrum_orm-0.1.22}/python/ferrum/session.py +0 -0
|
@@ -223,7 +223,7 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
|
|
|
223
223
|
|
|
224
224
|
[[package]]
|
|
225
225
|
name = "ferrum-core"
|
|
226
|
-
version = "0.1.
|
|
226
|
+
version = "0.1.22"
|
|
227
227
|
dependencies = [
|
|
228
228
|
"criterion",
|
|
229
229
|
"proptest",
|
|
@@ -234,7 +234,7 @@ dependencies = [
|
|
|
234
234
|
|
|
235
235
|
[[package]]
|
|
236
236
|
name = "ferrum-migrate"
|
|
237
|
-
version = "0.1.
|
|
237
|
+
version = "0.1.22"
|
|
238
238
|
dependencies = [
|
|
239
239
|
"ferrum-core",
|
|
240
240
|
"serde",
|
|
@@ -243,7 +243,7 @@ dependencies = [
|
|
|
243
243
|
|
|
244
244
|
[[package]]
|
|
245
245
|
name = "ferrum-pyo3"
|
|
246
|
-
version = "0.1.
|
|
246
|
+
version = "0.1.22"
|
|
247
247
|
dependencies = [
|
|
248
248
|
"ferrum-core",
|
|
249
249
|
"ferrum-sql",
|
|
@@ -255,7 +255,7 @@ dependencies = [
|
|
|
255
255
|
|
|
256
256
|
[[package]]
|
|
257
257
|
name = "ferrum-sql"
|
|
258
|
-
version = "0.1.
|
|
258
|
+
version = "0.1.22"
|
|
259
259
|
dependencies = [
|
|
260
260
|
"criterion",
|
|
261
261
|
"ferrum-core",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ferrum-orm
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.22
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Framework :: AsyncIO
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -216,6 +216,11 @@ class Event(Model):
|
|
|
216
216
|
|
|
217
217
|
`makemigrations` honours these field attributes:
|
|
218
218
|
- `db_default` / `nullable` are written into `CREATE TABLE` and `ADD COLUMN` DDL.
|
|
219
|
+
- A plain Python default also becomes the column `DEFAULT` when it has a safe SQL
|
|
220
|
+
literal form: `bool`, `""`, and finite `int` / `float` / `Decimal` numbers (e.g.
|
|
221
|
+
`int = 14` → `DEFAULT 14`, `float = 1e-06` → `DEFAULT 1e-06`). Other defaults
|
|
222
|
+
(non-empty strings, dates, objects) are applied by Python on insert only. A
|
|
223
|
+
non-finite number (`inf`, `nan`) fails `makemigrations` with `FERR-M001`.
|
|
219
224
|
- `db_index=True` emits `CREATE INDEX` after the table op.
|
|
220
225
|
- A `ForeignKey` / `OneToOne` references the target model's primary-key column, so
|
|
221
226
|
natural keys work (e.g. `REFERENCES catalog_version(version)`). A target with a
|
|
@@ -144,6 +144,11 @@ class Event(Model):
|
|
|
144
144
|
|
|
145
145
|
`makemigrations` honours these field attributes:
|
|
146
146
|
- `db_default` / `nullable` are written into `CREATE TABLE` and `ADD COLUMN` DDL.
|
|
147
|
+
- A plain Python default also becomes the column `DEFAULT` when it has a safe SQL
|
|
148
|
+
literal form: `bool`, `""`, and finite `int` / `float` / `Decimal` numbers (e.g.
|
|
149
|
+
`int = 14` → `DEFAULT 14`, `float = 1e-06` → `DEFAULT 1e-06`). Other defaults
|
|
150
|
+
(non-empty strings, dates, objects) are applied by Python on insert only. A
|
|
151
|
+
non-finite number (`inf`, `nan`) fails `makemigrations` with `FERR-M001`.
|
|
147
152
|
- `db_index=True` emits `CREATE INDEX` after the table op.
|
|
148
153
|
- A `ForeignKey` / `OneToOne` references the target model's primary-key column, so
|
|
149
154
|
natural keys work (e.g. `REFERENCES catalog_version(version)`). A target with a
|
|
@@ -22,6 +22,7 @@ from rich import print as rprint
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
23
|
from ferrum.models import Model
|
|
24
24
|
|
|
25
|
+
from ferrum.errors import FerrumError
|
|
25
26
|
from ferrum.migrations import loader
|
|
26
27
|
from ferrum.migrations.orchestrator import ColumnState, IndexState, SchemaState, compute_plan
|
|
27
28
|
|
|
@@ -308,7 +309,11 @@ async def run_makemigrations(
|
|
|
308
309
|
existing_state = _build_existing_state(existing_migrations)
|
|
309
310
|
model_classes = _get_all_model_subclasses()
|
|
310
311
|
|
|
311
|
-
|
|
312
|
+
try:
|
|
313
|
+
plan = compute_plan(model_classes, existing_state)
|
|
314
|
+
except FerrumError as exc:
|
|
315
|
+
print(f"Error: {exc}", file=sys.stderr)
|
|
316
|
+
return 2
|
|
312
317
|
ops = plan.get("ops", [])
|
|
313
318
|
|
|
314
319
|
if not ops:
|
|
@@ -26,6 +26,7 @@ import hashlib
|
|
|
26
26
|
import json
|
|
27
27
|
import re
|
|
28
28
|
from dataclasses import dataclass, field
|
|
29
|
+
from decimal import Decimal
|
|
29
30
|
from enum import Enum
|
|
30
31
|
from typing import TYPE_CHECKING, Any, ClassVar
|
|
31
32
|
|
|
@@ -274,6 +275,9 @@ _DEFAULT_VALUE_ALLOWLIST: frozenset[str] = frozenset(
|
|
|
274
275
|
)
|
|
275
276
|
|
|
276
277
|
|
|
278
|
+
_NUMERIC_LITERAL_RE = re.compile(r"-?\d+(\.\d+)?([eE][-+]?\d+)?")
|
|
279
|
+
|
|
280
|
+
|
|
277
281
|
def _normalize_column_default(default: Any) -> str: # noqa: ANN401
|
|
278
282
|
"""Normalize a migration default value to its SQL literal token."""
|
|
279
283
|
text = str(default)
|
|
@@ -282,8 +286,31 @@ def _normalize_column_default(default: Any) -> str: # noqa: ANN401
|
|
|
282
286
|
return text
|
|
283
287
|
|
|
284
288
|
|
|
285
|
-
def
|
|
286
|
-
"""
|
|
289
|
+
def _is_allowed_default(token: str) -> bool:
|
|
290
|
+
"""Return whether *token* may appear unquoted after ``DEFAULT`` in DDL.
|
|
291
|
+
|
|
292
|
+
The single rule shared by the generator and the DDL check: an allowlisted
|
|
293
|
+
token, or a plain numeric literal (sign, digits, fraction, exponent only).
|
|
294
|
+
"""
|
|
295
|
+
return token.upper() in _DEFAULT_VALUE_ALLOWLIST or bool(_NUMERIC_LITERAL_RE.fullmatch(token))
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def _python_default_to_sql(
|
|
299
|
+
*,
|
|
300
|
+
value: Any, # noqa: ANN401
|
|
301
|
+
field_meta: FieldMeta,
|
|
302
|
+
model_name: str,
|
|
303
|
+
) -> str | None:
|
|
304
|
+
"""Map a Python-side field default to an allowed SQL DEFAULT literal, if possible.
|
|
305
|
+
|
|
306
|
+
Returns ``None`` when the default has no DB-side form (the value is then
|
|
307
|
+
applied by Python on insert only).
|
|
308
|
+
|
|
309
|
+
Raises:
|
|
310
|
+
FerrumMigrationError: a numeric default that cannot be written as a SQL
|
|
311
|
+
literal (``inf``, ``nan``), so ``makemigrations`` fails instead of
|
|
312
|
+
``migrate``.
|
|
313
|
+
"""
|
|
287
314
|
if value is None:
|
|
288
315
|
return None
|
|
289
316
|
field_type = field_meta.field_type
|
|
@@ -293,11 +320,24 @@ def _python_default_to_sql(*, value: Any, field_meta: FieldMeta) -> str | None:
|
|
|
293
320
|
return None
|
|
294
321
|
if field_type == "bool" and isinstance(value, bool):
|
|
295
322
|
return "TRUE" if value else "FALSE"
|
|
296
|
-
if
|
|
297
|
-
return
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
323
|
+
if isinstance(value, bool):
|
|
324
|
+
return None
|
|
325
|
+
token: str | None = None
|
|
326
|
+
if (field_type in ("int", "big_int") and isinstance(value, int)) or (
|
|
327
|
+
field_type == "float" and isinstance(value, (int, float))
|
|
328
|
+
):
|
|
329
|
+
token = str(value)
|
|
330
|
+
elif field_type == "decimal" and isinstance(value, (int, Decimal)):
|
|
331
|
+
token = format(value, "f") if isinstance(value, Decimal) else str(value)
|
|
332
|
+
if token is None:
|
|
333
|
+
return None
|
|
334
|
+
if not _is_allowed_default(token):
|
|
335
|
+
raise FerrumMigrationError(
|
|
336
|
+
f"Model {model_name!r} field {field_meta.name!r}: the default is not a "
|
|
337
|
+
"finite number, so it cannot be a SQL DEFAULT. Use a finite default or "
|
|
338
|
+
"set db_default=. [FERR-M001]"
|
|
339
|
+
)
|
|
340
|
+
return token
|
|
301
341
|
|
|
302
342
|
|
|
303
343
|
def _quote_ident(name: str, dialect: str) -> str:
|
|
@@ -472,7 +512,7 @@ def _col_def(col: dict[str, Any], *, dialect: str = "postgres") -> str:
|
|
|
472
512
|
parts.append("NOT NULL")
|
|
473
513
|
if default is not None:
|
|
474
514
|
normalized = _normalize_column_default(default)
|
|
475
|
-
if normalized
|
|
515
|
+
if not _is_allowed_default(normalized):
|
|
476
516
|
raise FerrumMigrationError(
|
|
477
517
|
f"Unsupported DEFAULT value {default!r}. "
|
|
478
518
|
f"Only simple literals are allowed. [FERR-M001]"
|
|
@@ -594,7 +634,7 @@ def _op_to_sql(op: dict[str, Any], *, dialect: str = "postgres") -> str:
|
|
|
594
634
|
default = op.get("default")
|
|
595
635
|
if default is not None:
|
|
596
636
|
default_token = _normalize_column_default(default)
|
|
597
|
-
if default_token
|
|
637
|
+
if not _is_allowed_default(default_token):
|
|
598
638
|
raise FerrumMigrationError(
|
|
599
639
|
f"Default value {default!r} is not in the migration allowlist. [FERR-M001]"
|
|
600
640
|
)
|
|
@@ -853,7 +893,7 @@ def _index_columns_sql(
|
|
|
853
893
|
return ", ".join(parts)
|
|
854
894
|
|
|
855
895
|
|
|
856
|
-
def _field_to_col_def(field_meta: FieldMeta, *, is_pk: bool) -> dict[str, Any]:
|
|
896
|
+
def _field_to_col_def(field_meta: FieldMeta, *, is_pk: bool, model_name: str) -> dict[str, Any]:
|
|
857
897
|
"""Convert a ``FieldMeta`` to a column-def dict for the plan JSON.
|
|
858
898
|
|
|
859
899
|
Security: all names come from model-metadata allowlists — never user input.
|
|
@@ -870,7 +910,9 @@ def _field_to_col_def(field_meta: FieldMeta, *, is_pk: bool) -> dict[str, Any]:
|
|
|
870
910
|
# A Python-side default on a serial PK (e.g. ``id: int = 0``) is an
|
|
871
911
|
# insert-time value, not a DB default: the sequence owns the DB default.
|
|
872
912
|
if default is None and sql_type.upper() not in _SERIAL_SQL_TYPES:
|
|
873
|
-
default = _python_default_to_sql(
|
|
913
|
+
default = _python_default_to_sql(
|
|
914
|
+
value=field_meta.python_default, field_meta=field_meta, model_name=model_name
|
|
915
|
+
)
|
|
874
916
|
col_def: dict[str, Any] = {
|
|
875
917
|
"name": field_meta.column_name,
|
|
876
918
|
"sql_type": sql_type,
|
|
@@ -927,7 +969,7 @@ def _autodiff_existing_table(
|
|
|
927
969
|
|
|
928
970
|
Security: all identifiers come from model metadata allowlists or
|
|
929
971
|
``SchemaState`` that was itself built from prior migration ops — never user
|
|
930
|
-
input. Default values are checked
|
|
972
|
+
input. Default values are checked by ``_is_allowed_default`` in
|
|
931
973
|
``_op_to_sql`` when the plan is applied.
|
|
932
974
|
|
|
933
975
|
Out of scope: sql_type changes, renames, drops (unchanged v0.1 rule).
|
|
@@ -989,7 +1031,11 @@ def _autodiff_existing_table(
|
|
|
989
1031
|
col_state = existing_col_attrs[f.column_name]
|
|
990
1032
|
|
|
991
1033
|
desired_not_null = not f.nullable
|
|
992
|
-
|
|
1034
|
+
# Same default the generator writes for a new column (db_default, else
|
|
1035
|
+
# the Python default when it has a SQL literal form).
|
|
1036
|
+
desired_default = _field_to_col_def(f, is_pk=f.pk, model_name=metadata.model_name)[
|
|
1037
|
+
"default"
|
|
1038
|
+
]
|
|
993
1039
|
|
|
994
1040
|
# Compare case-insensitively to handle legacy lowercase defaults in state.
|
|
995
1041
|
state_default_upper = col_state.default.upper() if col_state.default else None
|
|
@@ -1109,7 +1155,7 @@ def compute_plan(
|
|
|
1109
1155
|
# _col_def skips the inline PRIMARY KEY (the constraint is table-level).
|
|
1110
1156
|
col_defs: list[dict[str, Any]] = []
|
|
1111
1157
|
for f in metadata.fields:
|
|
1112
|
-
cd = _field_to_col_def(f, is_pk=f.pk)
|
|
1158
|
+
cd = _field_to_col_def(f, is_pk=f.pk, model_name=metadata.model_name)
|
|
1113
1159
|
if is_composite_pk and f.pk:
|
|
1114
1160
|
cd = {**cd, "primary_key": False, "composite_pk": True}
|
|
1115
1161
|
col_defs.append(cd)
|
|
@@ -1240,7 +1286,7 @@ def compute_plan(
|
|
|
1240
1286
|
|
|
1241
1287
|
for f in metadata.fields:
|
|
1242
1288
|
if f.column_name not in existing_col_names:
|
|
1243
|
-
col_def = _field_to_col_def(f, is_pk=False)
|
|
1289
|
+
col_def = _field_to_col_def(f, is_pk=False, model_name=metadata.model_name)
|
|
1244
1290
|
ops.append(
|
|
1245
1291
|
{
|
|
1246
1292
|
"kind": "add_column",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|