ferrum-orm 0.1.19__tar.gz → 0.1.20__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.19 → ferrum_orm-0.1.20}/Cargo.lock +6 -6
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/Cargo.toml +1 -1
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/PKG-INFO +1 -1
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/pyproject.toml +2 -8
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/__init__.py +1 -1
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/contrib/fastapi.py +2 -2
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/orchestrator.py +19 -3
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/LICENSE +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/README.md +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/Cargo.toml +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/benches/hydrate.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/src/compile/mod.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/src/error.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/src/hydrate/mod.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/src/ir/metadata.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/src/ir/mod.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/src/lib.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-core/src/migrate/mod.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-pyo3/Cargo.toml +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-pyo3/src/lib.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/Cargo.toml +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/benches/compile.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/dialect.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/emit.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/mod.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/mssql.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/mysql.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/postgres.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/sqlite.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/lib.rs +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/_native.pyi +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/__init__.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/app.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/bootstrap.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/check_schema_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/init.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/inspectdb_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/makemigrations_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/migrate_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/migrations_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/resetdb_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/revert_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/showmigrations_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/cli/sqlmigrate_cmd.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/config.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/connection.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/contrib/__init__.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/drivers/__init__.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/drivers/mssql.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/drivers/mysql.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/drivers/postgres.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/drivers/protocol.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/drivers/sqlite.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/drivers/streaming.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/echo.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/errors.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/expressions.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/ext/__init__.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/ext/fts.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/ext/pgvector.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/hooks.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/__init__.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/autodiff.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/base.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/coordinator.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/drift.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/__init__.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/mssql.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/mysql.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/postgres.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/sqlite.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/gates.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/introspect.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/ledger.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/loader.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/operations.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/migrations/tokens.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/models.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/observability.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/py.typed +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/queryset.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/registry.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/relations.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/routing.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/python/ferrum/runtime.py +0 -0
- {ferrum_orm-0.1.19 → ferrum_orm-0.1.20}/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.20"
|
|
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.20"
|
|
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.20"
|
|
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.20"
|
|
259
259
|
dependencies = [
|
|
260
260
|
"criterion",
|
|
261
261
|
"ferrum-core",
|
|
@@ -750,9 +750,9 @@ dependencies = [
|
|
|
750
750
|
|
|
751
751
|
[[package]]
|
|
752
752
|
name = "rustix"
|
|
753
|
-
version = "1.1.
|
|
753
|
+
version = "1.1.6"
|
|
754
754
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
755
|
-
checksum = "
|
|
755
|
+
checksum = "e5e76742e5294153d4dde1207dbec5bdd81eef6fabdc0d2118babadabfd858aa"
|
|
756
756
|
dependencies = [
|
|
757
757
|
"bitflags",
|
|
758
758
|
"errno",
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ferrum-orm"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.20"
|
|
8
8
|
description = "Next-generation async ORM for Python with a Rust-powered core"
|
|
9
9
|
license = { text = "Apache-2.0" }
|
|
10
10
|
readme = "README.md"
|
|
@@ -180,10 +180,4 @@ markers = [
|
|
|
180
180
|
# Do not run integration/security by default locally; require explicit -m flag.
|
|
181
181
|
addopts = "-m 'not integration and not security'"
|
|
182
182
|
|
|
183
|
-
#
|
|
184
|
-
# import-linter
|
|
185
|
-
# ---------------------------------------------------------------------------
|
|
186
|
-
[tool.importlinter]
|
|
187
|
-
root_packages = ["ferrum"]
|
|
188
|
-
include_external_packages = true
|
|
189
|
-
contracts_file = ".importlinter"
|
|
183
|
+
# import-linter is configured in .importlinter.
|
|
@@ -373,7 +373,7 @@ def _import_fastapi_users_db_protocol() -> Any: # noqa: ANN401 — soft import
|
|
|
373
373
|
without a new Ferrum-side hard dependency.
|
|
374
374
|
"""
|
|
375
375
|
try:
|
|
376
|
-
from fastapi_users.db.base import BaseUserDatabase # ty: ignore[
|
|
376
|
+
from fastapi_users.db.base import BaseUserDatabase # ty: ignore[import-not-found]
|
|
377
377
|
except ImportError as exc: # pragma: no cover — exercised by unit test
|
|
378
378
|
raise ImportError(
|
|
379
379
|
"FerrumUserDatabase requires the optional 'fastapi-users' package. "
|
|
@@ -545,7 +545,7 @@ class FerrumUserDatabase:
|
|
|
545
545
|
def _raise_user_already_exists(exc: FerrumIntegrityError) -> None:
|
|
546
546
|
"""Translate a Ferrum unique/integrity error into UserAlreadyExists."""
|
|
547
547
|
try:
|
|
548
|
-
from fastapi_users.exceptions import UserAlreadyExists # ty: ignore[
|
|
548
|
+
from fastapi_users.exceptions import UserAlreadyExists # ty: ignore[import-not-found]
|
|
549
549
|
except ImportError: # pragma: no cover — exercised by unit test
|
|
550
550
|
# Without fastapi-users installed there is no UserAlreadyExists
|
|
551
551
|
# to raise; re-raise the Ferrum error so the caller still sees
|
|
@@ -196,6 +196,13 @@ def _validate_timeout(value: str | None, name: str) -> None:
|
|
|
196
196
|
)
|
|
197
197
|
|
|
198
198
|
|
|
199
|
+
# Serial pseudo-types carry an implicit sequence DEFAULT; PostgreSQL rejects a
|
|
200
|
+
# second DEFAULT on the same column (SQLSTATE 42601).
|
|
201
|
+
_SERIAL_SQL_TYPES: frozenset[str] = frozenset(
|
|
202
|
+
{"SMALLSERIAL", "SERIAL2", "SERIAL", "SERIAL4", "BIGSERIAL", "SERIAL8"}
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
|
|
199
206
|
# SQL type allowlist — only these tokens may appear in DDL type position.
|
|
200
207
|
# Prevents DDL injection if upstream metadata validation is bypassed.
|
|
201
208
|
_SQL_TYPE_ALLOWLIST: frozenset[str] = frozenset(
|
|
@@ -426,7 +433,13 @@ def _col_def(col: dict[str, Any], *, dialect: str = "postgres") -> str:
|
|
|
426
433
|
For composite-PK tables ``primary_key`` may be ``False`` on individual columns
|
|
427
434
|
(the table-level constraint is emitted by ``_op_to_sql`` for ``create_table``).
|
|
428
435
|
"""
|
|
429
|
-
|
|
436
|
+
source_type = str(col.get("sql_type", "TEXT"))
|
|
437
|
+
if col.get("default") is not None and source_type.strip().upper() in _SERIAL_SQL_TYPES:
|
|
438
|
+
raise FerrumMigrationError(
|
|
439
|
+
f"Column {col['name']!r} is {source_type.upper()}, which already has a "
|
|
440
|
+
"sequence DEFAULT. Remove default= from this column. [FERR-M001]"
|
|
441
|
+
)
|
|
442
|
+
sql_type = _map_sql_type(source_type, dialect)
|
|
430
443
|
base_type = sql_type.split("(")[0].upper()
|
|
431
444
|
# Array types end with "[]"; strip that suffix before allowlist check.
|
|
432
445
|
base_type_check = base_type.rstrip("[]") if base_type.endswith("[]") else base_type
|
|
@@ -841,12 +854,15 @@ def _field_to_col_def(field_meta: FieldMeta, *, is_pk: bool) -> dict[str, Any]:
|
|
|
841
854
|
parameterised column types (``VARCHAR(n)``, ``NUMERIC(p,s)``) are emitted
|
|
842
855
|
correctly.
|
|
843
856
|
"""
|
|
857
|
+
sql_type = field_meta.sql_type
|
|
844
858
|
default = field_meta.db_default
|
|
845
|
-
|
|
859
|
+
# A Python-side default on a serial PK (e.g. ``id: int = 0``) is an
|
|
860
|
+
# insert-time value, not a DB default: the sequence owns the DB default.
|
|
861
|
+
if default is None and sql_type.upper() not in _SERIAL_SQL_TYPES:
|
|
846
862
|
default = _python_default_to_sql(value=field_meta.python_default, field_meta=field_meta)
|
|
847
863
|
return {
|
|
848
864
|
"name": field_meta.column_name,
|
|
849
|
-
"sql_type":
|
|
865
|
+
"sql_type": sql_type,
|
|
850
866
|
"not_null": not field_meta.nullable,
|
|
851
867
|
"default": default,
|
|
852
868
|
"primary_key": is_pk,
|
|
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
|
|
File without changes
|