ferrum-orm 0.1.17__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.17 → ferrum_orm-0.1.20}/Cargo.lock +8 -8
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/Cargo.toml +1 -1
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/PKG-INFO +64 -10
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/README.md +62 -8
- ferrum_orm-0.1.20/crates/ferrum-core/benches/hydrate.rs +384 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/src/ir/metadata.rs +6 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/src/ir/mod.rs +4 -0
- ferrum_orm-0.1.20/crates/ferrum-sql/benches/compile.rs +813 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/emit.rs +13 -5
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/pyproject.toml +5 -11
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/__init__.py +11 -3
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/_native.pyi +66 -11
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/app.py +69 -0
- ferrum_orm-0.1.20/python/ferrum/cli/check_schema_cmd.py +148 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/migrate_cmd.py +142 -51
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/migrations_cmd.py +0 -1
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/connection.py +465 -27
- ferrum_orm-0.1.20/python/ferrum/contrib/__init__.py +12 -0
- ferrum_orm-0.1.20/python/ferrum/contrib/fastapi.py +554 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/drivers/mysql.py +60 -18
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/drivers/postgres.py +250 -26
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/drivers/protocol.py +52 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/drivers/sqlite.py +65 -12
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/echo.py +2 -2
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/errors.py +391 -27
- ferrum_orm-0.1.20/python/ferrum/expressions.py +176 -0
- ferrum_orm-0.1.20/python/ferrum/ext/__init__.py +17 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/ext/pgvector.py +132 -41
- ferrum_orm-0.1.20/python/ferrum/hooks.py +499 -0
- ferrum_orm-0.1.20/python/ferrum/migrations/autodiff.py +665 -0
- ferrum_orm-0.1.20/python/ferrum/migrations/base.py +85 -0
- ferrum_orm-0.1.20/python/ferrum/migrations/coordinator.py +1031 -0
- ferrum_orm-0.1.20/python/ferrum/migrations/drift.py +1488 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/ledger.py +138 -5
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/loader.py +69 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/operations.py +17 -3
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/orchestrator.py +906 -22
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/models.py +860 -8
- ferrum_orm-0.1.20/python/ferrum/observability.py +554 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/queryset.py +388 -50
- ferrum_orm-0.1.20/python/ferrum/registry.py +116 -0
- ferrum_orm-0.1.20/python/ferrum/relations.py +683 -0
- ferrum_orm-0.1.20/python/ferrum/routing.py +376 -0
- ferrum_orm-0.1.20/python/ferrum/runtime.py +433 -0
- ferrum_orm-0.1.20/python/ferrum/session.py +344 -0
- ferrum_orm-0.1.17/crates/ferrum-core/benches/hydrate.rs +0 -101
- ferrum_orm-0.1.17/crates/ferrum-sql/benches/compile.rs +0 -162
- ferrum_orm-0.1.17/python/ferrum/contrib/__init__.py +0 -5
- ferrum_orm-0.1.17/python/ferrum/contrib/fastapi.py +0 -75
- ferrum_orm-0.1.17/python/ferrum/expressions.py +0 -82
- ferrum_orm-0.1.17/python/ferrum/ext/__init__.py +0 -5
- ferrum_orm-0.1.17/python/ferrum/hooks.py +0 -270
- ferrum_orm-0.1.17/python/ferrum/migrations/base.py +0 -50
- ferrum_orm-0.1.17/python/ferrum/migrations/drift.py +0 -377
- ferrum_orm-0.1.17/python/ferrum/observability.py +0 -159
- ferrum_orm-0.1.17/python/ferrum/registry.py +0 -55
- ferrum_orm-0.1.17/python/ferrum/relations.py +0 -378
- ferrum_orm-0.1.17/python/ferrum/runtime.py +0 -240
- ferrum_orm-0.1.17/python/ferrum/session.py +0 -171
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/LICENSE +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/Cargo.toml +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/src/compile/mod.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/src/error.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/src/hydrate/mod.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/src/lib.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-core/src/migrate/mod.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-pyo3/Cargo.toml +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-pyo3/src/lib.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/Cargo.toml +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/dialect.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/mod.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/mssql.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/mysql.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/postgres.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/fts/sqlite.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/crates/ferrum-sql/src/lib.rs +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/__init__.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/bootstrap.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/init.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/inspectdb_cmd.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/makemigrations_cmd.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/resetdb_cmd.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/revert_cmd.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/showmigrations_cmd.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/cli/sqlmigrate_cmd.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/config.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/drivers/__init__.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/drivers/mssql.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/drivers/streaming.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/ext/fts.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/__init__.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/__init__.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/mssql.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/mysql.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/postgres.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/fts/sqlite.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/gates.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/introspect.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/migrations/tokens.py +0 -0
- {ferrum_orm-0.1.17 → ferrum_orm-0.1.20}/python/ferrum/py.typed +0 -0
|
@@ -25,9 +25,9 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
|
|
25
25
|
|
|
26
26
|
[[package]]
|
|
27
27
|
name = "anyhow"
|
|
28
|
-
version = "1.0.
|
|
28
|
+
version = "1.0.104"
|
|
29
29
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
30
|
-
checksum = "
|
|
30
|
+
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
|
|
31
31
|
|
|
32
32
|
[[package]]
|
|
33
33
|
name = "autocfg"
|
|
@@ -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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ferrum-orm
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.20
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Framework :: AsyncIO
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -25,7 +25,7 @@ Requires-Dist: ferrum-orm[cli] ; extra == 'all'
|
|
|
25
25
|
Requires-Dist: ferrum-orm[dotenv] ; extra == 'all'
|
|
26
26
|
Requires-Dist: typer>=0.12 ; extra == 'cli'
|
|
27
27
|
Requires-Dist: rich>=13 ; extra == 'cli'
|
|
28
|
-
Requires-Dist: ferrum-orm[pg,cli,dotenv] ; extra == 'dev'
|
|
28
|
+
Requires-Dist: ferrum-orm[pg,mysql,sqlite,mssql,cli,dotenv] ; extra == 'dev'
|
|
29
29
|
Requires-Dist: maturin>=1.7,<2 ; extra == 'dev'
|
|
30
30
|
Requires-Dist: pytest>=8 ; extra == 'dev'
|
|
31
31
|
Requires-Dist: pytest-asyncio>=0.23 ; extra == 'dev'
|
|
@@ -96,12 +96,25 @@ Ferrum aims to provide all four.
|
|
|
96
96
|
- Pydantic-first models
|
|
97
97
|
- Django-inspired ORM experience
|
|
98
98
|
- Rust-powered query engine
|
|
99
|
-
- PostgreSQL-first architecture
|
|
99
|
+
- PostgreSQL-first architecture. MySQL, SQLite, and SQL Server extras are best-effort thin parity — not production-supported and not production-readiness release gates
|
|
100
100
|
- Type-safe query construction
|
|
101
101
|
- Automatic migrations
|
|
102
102
|
- High-performance result hydration
|
|
103
103
|
- Production-ready observability
|
|
104
104
|
|
|
105
|
+
### Production-readiness execution
|
|
106
|
+
|
|
107
|
+
Ferrum is still alpha. The remaining production work for Ticket Analyzer and an
|
|
108
|
+
async-refactored Org AI Platform is tracked in
|
|
109
|
+
[the production-readiness plan](.cursor/plans/ferrum-production-readiness_6b5f422d.plan.md).
|
|
110
|
+
Execution is wave-based and supports parallel agents through disjoint file ownership,
|
|
111
|
+
per-workstream state, immutable evidence logs, and an independent verification gate.
|
|
112
|
+
|
|
113
|
+
Every task follows `Specify → Plan → Tasks → Implement`; every executor run follows
|
|
114
|
+
`Load → Execute → Validate executor output → Verify independently → Update state`.
|
|
115
|
+
See [.agent-work/production-readiness/](.agent-work/production-readiness/) for the durable
|
|
116
|
+
execution contract and current aggregate state.
|
|
117
|
+
|
|
105
118
|
---
|
|
106
119
|
|
|
107
120
|
## Quick Example
|
|
@@ -285,7 +298,9 @@ This allows Ferrum to maintain a Pythonic API without sacrificing performance.
|
|
|
285
298
|
### Cross-Driver Full-Text Search
|
|
286
299
|
|
|
287
300
|
Native full-text search across PostgreSQL, MySQL, SQLite FTS5, and SQL Server — one
|
|
288
|
-
QuerySet API, dialect-specific SQL emit and migration DDL.
|
|
301
|
+
QuerySet API, dialect-specific SQL emit and migration DDL. Cross-dialect FTS on
|
|
302
|
+
MySQL / SQLite / SQL Server is a **thin-extra** capability, not a P0
|
|
303
|
+
production-readiness release gate. PostgreSQL FTS is the production-readiness target.
|
|
289
304
|
|
|
290
305
|
**Query modes** (filter lookups and ranking):
|
|
291
306
|
|
|
@@ -366,7 +381,7 @@ and [API Reference](docs/api-reference.md) for per-dialect DDL and operator mapp
|
|
|
366
381
|
- [x] Migrations (schema diff, apply, revert, CLI)
|
|
367
382
|
- [x] Relationships (ForeignKey, OneToOne, ManyToMany)
|
|
368
383
|
- [x] pgvector KNN search and HNSW/IVFFLAT index DDL
|
|
369
|
-
- [x] Full-text search (
|
|
384
|
+
- [x] Full-text search (PostgreSQL is the P0 gate; MySQL/SQLite/SQL Server FTS is thin-extra)
|
|
370
385
|
- [x] Observability hooks (Tier A/B/C)
|
|
371
386
|
- [x] CLI (`makemigrations`, `migrate`, `revert`, `showmigrations`, `inspectdb`, `resetdb`)
|
|
372
387
|
|
|
@@ -397,7 +412,11 @@ and [API Reference](docs/api-reference.md) for per-dialect DDL and operator mapp
|
|
|
397
412
|
|
|
398
413
|
Ferrum is currently in active development.
|
|
399
414
|
|
|
400
|
-
The API is not yet stable
|
|
415
|
+
The API is not yet stable. **0.x has no compatibility guarantee**: SemVer MINOR and PATCH
|
|
416
|
+
may both break. After 1.0, public API and migration-ops breaks require a deprecation
|
|
417
|
+
window of at least one minor release and 90 days, whichever is longer. Generated SQL is
|
|
418
|
+
never a compatibility surface. Compatibility policy: `AGENTS.md` §5a. Thin extras:
|
|
419
|
+
`AGENTS.md` §2.6. See also `CHANGELOG.md`.
|
|
401
420
|
|
|
402
421
|
## Installation
|
|
403
422
|
|
|
@@ -430,10 +449,45 @@ pip install ferrum-orm
|
|
|
430
449
|
Bare `ferrum-orm` installs Pydantic and the Rust core only. Choose a driver extra
|
|
431
450
|
(`pg`, `mysql`, `sqlite`, or `mssql`) before calling `ferrum.connect()`.
|
|
432
451
|
|
|
433
|
-
MySQL, SQLite, and SQL Server are **thin-parity** backends: they
|
|
434
|
-
and
|
|
435
|
-
|
|
436
|
-
|
|
452
|
+
MySQL, SQLite, and SQL Server are **best-effort thin-parity** backends: they are **not
|
|
453
|
+
production-supported** and are **not production-readiness release gates**. Core CRUD is
|
|
454
|
+
exercised across all four drivers; advanced behavior is capability-gated rather than
|
|
455
|
+
emulated with incompatible SQL. The integration-suite registry
|
|
456
|
+
(`tests/python/integration/backends.py`) is the coverage matrix — what is tested,
|
|
457
|
+
not a stability or production-support claim. PostgreSQL claims every capability.
|
|
458
|
+
MySQL and SQL Server claim full-text search and composite primary keys only.
|
|
459
|
+
SQLite claims `RETURNING`, full-text search, and composite primary keys.
|
|
460
|
+
|
|
461
|
+
| Capability | PostgreSQL | MySQL | SQLite | SQL Server |
|
|
462
|
+
| ---------- | :--------: | :---: | :----: | :--------: |
|
|
463
|
+
| Transactions | ✅ | — | — | — |
|
|
464
|
+
| Savepoints | ✅ | — | — | — |
|
|
465
|
+
| Cursor streaming | ✅ | — | — | — |
|
|
466
|
+
| Bulk update | ✅ | — | — | — |
|
|
467
|
+
| Aggregates / grouping | ✅ | — | — | — |
|
|
468
|
+
| Upsert | ✅ | — | — | — |
|
|
469
|
+
| Returning rows | ✅ | — | ✅ | — |
|
|
470
|
+
| Row-level security helpers | ✅ | — | — | — |
|
|
471
|
+
| pgvector | ✅ | — | — | — |
|
|
472
|
+
| Full-text search | ✅ | ✅ | ✅ | ✅ |
|
|
473
|
+
| JSON operators | ✅ | — | — | — |
|
|
474
|
+
| Case-insensitive `ILIKE` | ✅ | — | — | — |
|
|
475
|
+
| Array columns | ✅ | — | — | — |
|
|
476
|
+
| Alter column | ✅ | — | — | — |
|
|
477
|
+
| Composite primary keys | ✅ | ✅ | ✅ | ✅ |
|
|
478
|
+
| Stored-function calls | ✅ | — | — | — |
|
|
479
|
+
|
|
480
|
+
Unsupported capabilities fail with a typed Ferrum error before backend SQL is
|
|
481
|
+
executed. Transactions, savepoints, aggregates, upsert, alter-column, and
|
|
482
|
+
stored-function calls are PostgreSQL-only in this matrix; thin extras raise at
|
|
483
|
+
the Python/compiler boundary rather than sending Postgres SQL. Pull requests
|
|
484
|
+
exercise PostgreSQL and SQLite, while the nightly integration matrix runs
|
|
485
|
+
PostgreSQL, MySQL, SQLite, and SQL Server independently. SQLite on PRs is CI
|
|
486
|
+
coverage, not a production-readiness gate. Cross-dialect FTS in the matrix is
|
|
487
|
+
thin-extra coverage, not a P0 release gate.
|
|
488
|
+
|
|
489
|
+
SQL Server connects via `aioodbc`/`pyodbc` and requires a system ODBC driver such
|
|
490
|
+
as `msodbcsql18`; DSNs use the `mssql://` or `sqlserver://` scheme.
|
|
437
491
|
|
|
438
492
|
### Wire format (advanced)
|
|
439
493
|
|
|
@@ -24,12 +24,25 @@ Ferrum aims to provide all four.
|
|
|
24
24
|
- Pydantic-first models
|
|
25
25
|
- Django-inspired ORM experience
|
|
26
26
|
- Rust-powered query engine
|
|
27
|
-
- PostgreSQL-first architecture
|
|
27
|
+
- PostgreSQL-first architecture. MySQL, SQLite, and SQL Server extras are best-effort thin parity — not production-supported and not production-readiness release gates
|
|
28
28
|
- Type-safe query construction
|
|
29
29
|
- Automatic migrations
|
|
30
30
|
- High-performance result hydration
|
|
31
31
|
- Production-ready observability
|
|
32
32
|
|
|
33
|
+
### Production-readiness execution
|
|
34
|
+
|
|
35
|
+
Ferrum is still alpha. The remaining production work for Ticket Analyzer and an
|
|
36
|
+
async-refactored Org AI Platform is tracked in
|
|
37
|
+
[the production-readiness plan](.cursor/plans/ferrum-production-readiness_6b5f422d.plan.md).
|
|
38
|
+
Execution is wave-based and supports parallel agents through disjoint file ownership,
|
|
39
|
+
per-workstream state, immutable evidence logs, and an independent verification gate.
|
|
40
|
+
|
|
41
|
+
Every task follows `Specify → Plan → Tasks → Implement`; every executor run follows
|
|
42
|
+
`Load → Execute → Validate executor output → Verify independently → Update state`.
|
|
43
|
+
See [.agent-work/production-readiness/](.agent-work/production-readiness/) for the durable
|
|
44
|
+
execution contract and current aggregate state.
|
|
45
|
+
|
|
33
46
|
---
|
|
34
47
|
|
|
35
48
|
## Quick Example
|
|
@@ -213,7 +226,9 @@ This allows Ferrum to maintain a Pythonic API without sacrificing performance.
|
|
|
213
226
|
### Cross-Driver Full-Text Search
|
|
214
227
|
|
|
215
228
|
Native full-text search across PostgreSQL, MySQL, SQLite FTS5, and SQL Server — one
|
|
216
|
-
QuerySet API, dialect-specific SQL emit and migration DDL.
|
|
229
|
+
QuerySet API, dialect-specific SQL emit and migration DDL. Cross-dialect FTS on
|
|
230
|
+
MySQL / SQLite / SQL Server is a **thin-extra** capability, not a P0
|
|
231
|
+
production-readiness release gate. PostgreSQL FTS is the production-readiness target.
|
|
217
232
|
|
|
218
233
|
**Query modes** (filter lookups and ranking):
|
|
219
234
|
|
|
@@ -294,7 +309,7 @@ and [API Reference](docs/api-reference.md) for per-dialect DDL and operator mapp
|
|
|
294
309
|
- [x] Migrations (schema diff, apply, revert, CLI)
|
|
295
310
|
- [x] Relationships (ForeignKey, OneToOne, ManyToMany)
|
|
296
311
|
- [x] pgvector KNN search and HNSW/IVFFLAT index DDL
|
|
297
|
-
- [x] Full-text search (
|
|
312
|
+
- [x] Full-text search (PostgreSQL is the P0 gate; MySQL/SQLite/SQL Server FTS is thin-extra)
|
|
298
313
|
- [x] Observability hooks (Tier A/B/C)
|
|
299
314
|
- [x] CLI (`makemigrations`, `migrate`, `revert`, `showmigrations`, `inspectdb`, `resetdb`)
|
|
300
315
|
|
|
@@ -325,7 +340,11 @@ and [API Reference](docs/api-reference.md) for per-dialect DDL and operator mapp
|
|
|
325
340
|
|
|
326
341
|
Ferrum is currently in active development.
|
|
327
342
|
|
|
328
|
-
The API is not yet stable
|
|
343
|
+
The API is not yet stable. **0.x has no compatibility guarantee**: SemVer MINOR and PATCH
|
|
344
|
+
may both break. After 1.0, public API and migration-ops breaks require a deprecation
|
|
345
|
+
window of at least one minor release and 90 days, whichever is longer. Generated SQL is
|
|
346
|
+
never a compatibility surface. Compatibility policy: `AGENTS.md` §5a. Thin extras:
|
|
347
|
+
`AGENTS.md` §2.6. See also `CHANGELOG.md`.
|
|
329
348
|
|
|
330
349
|
## Installation
|
|
331
350
|
|
|
@@ -358,10 +377,45 @@ pip install ferrum-orm
|
|
|
358
377
|
Bare `ferrum-orm` installs Pydantic and the Rust core only. Choose a driver extra
|
|
359
378
|
(`pg`, `mysql`, `sqlite`, or `mssql`) before calling `ferrum.connect()`.
|
|
360
379
|
|
|
361
|
-
MySQL, SQLite, and SQL Server are **thin-parity** backends: they
|
|
362
|
-
and
|
|
363
|
-
|
|
364
|
-
|
|
380
|
+
MySQL, SQLite, and SQL Server are **best-effort thin-parity** backends: they are **not
|
|
381
|
+
production-supported** and are **not production-readiness release gates**. Core CRUD is
|
|
382
|
+
exercised across all four drivers; advanced behavior is capability-gated rather than
|
|
383
|
+
emulated with incompatible SQL. The integration-suite registry
|
|
384
|
+
(`tests/python/integration/backends.py`) is the coverage matrix — what is tested,
|
|
385
|
+
not a stability or production-support claim. PostgreSQL claims every capability.
|
|
386
|
+
MySQL and SQL Server claim full-text search and composite primary keys only.
|
|
387
|
+
SQLite claims `RETURNING`, full-text search, and composite primary keys.
|
|
388
|
+
|
|
389
|
+
| Capability | PostgreSQL | MySQL | SQLite | SQL Server |
|
|
390
|
+
| ---------- | :--------: | :---: | :----: | :--------: |
|
|
391
|
+
| Transactions | ✅ | — | — | — |
|
|
392
|
+
| Savepoints | ✅ | — | — | — |
|
|
393
|
+
| Cursor streaming | ✅ | — | — | — |
|
|
394
|
+
| Bulk update | ✅ | — | — | — |
|
|
395
|
+
| Aggregates / grouping | ✅ | — | — | — |
|
|
396
|
+
| Upsert | ✅ | — | — | — |
|
|
397
|
+
| Returning rows | ✅ | — | ✅ | — |
|
|
398
|
+
| Row-level security helpers | ✅ | — | — | — |
|
|
399
|
+
| pgvector | ✅ | — | — | — |
|
|
400
|
+
| Full-text search | ✅ | ✅ | ✅ | ✅ |
|
|
401
|
+
| JSON operators | ✅ | — | — | — |
|
|
402
|
+
| Case-insensitive `ILIKE` | ✅ | — | — | — |
|
|
403
|
+
| Array columns | ✅ | — | — | — |
|
|
404
|
+
| Alter column | ✅ | — | — | — |
|
|
405
|
+
| Composite primary keys | ✅ | ✅ | ✅ | ✅ |
|
|
406
|
+
| Stored-function calls | ✅ | — | — | — |
|
|
407
|
+
|
|
408
|
+
Unsupported capabilities fail with a typed Ferrum error before backend SQL is
|
|
409
|
+
executed. Transactions, savepoints, aggregates, upsert, alter-column, and
|
|
410
|
+
stored-function calls are PostgreSQL-only in this matrix; thin extras raise at
|
|
411
|
+
the Python/compiler boundary rather than sending Postgres SQL. Pull requests
|
|
412
|
+
exercise PostgreSQL and SQLite, while the nightly integration matrix runs
|
|
413
|
+
PostgreSQL, MySQL, SQLite, and SQL Server independently. SQLite on PRs is CI
|
|
414
|
+
coverage, not a production-readiness gate. Cross-dialect FTS in the matrix is
|
|
415
|
+
thin-extra coverage, not a P0 release gate.
|
|
416
|
+
|
|
417
|
+
SQL Server connects via `aioodbc`/`pyodbc` and requires a system ODBC driver such
|
|
418
|
+
as `msodbcsql18`; DSNs use the `mssql://` or `sqlserver://` scheme.
|
|
365
419
|
|
|
366
420
|
### Wire format (advanced)
|
|
367
421
|
|