ferrum-orm 0.1.2__tar.gz → 0.1.3__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.
Files changed (79) hide show
  1. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/Cargo.lock +26 -4
  2. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/Cargo.toml +4 -1
  3. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/PKG-INFO +63 -29
  4. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/README.md +53 -27
  5. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-core/benches/hydrate.rs +1 -0
  6. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-core/src/compile/mod.rs +224 -29
  7. ferrum_orm-0.1.3/crates/ferrum-core/src/error.rs +111 -0
  8. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-core/src/hydrate/mod.rs +1 -0
  9. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-core/src/ir/metadata.rs +30 -1
  10. ferrum_orm-0.1.3/crates/ferrum-core/src/ir/mod.rs +276 -0
  11. ferrum_orm-0.1.3/crates/ferrum-core/src/migrate/mod.rs +91 -0
  12. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-pyo3/Cargo.toml +1 -0
  13. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-pyo3/src/lib.rs +168 -30
  14. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-sql/Cargo.toml +3 -0
  15. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-sql/benches/compile.rs +5 -0
  16. ferrum_orm-0.1.3/crates/ferrum-sql/src/dialect.rs +143 -0
  17. ferrum_orm-0.1.3/crates/ferrum-sql/src/emit.rs +1767 -0
  18. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/pyproject.toml +12 -4
  19. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/__init__.py +49 -3
  20. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/_native.pyi +34 -1
  21. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/app.py +20 -0
  22. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/bootstrap.py +3 -2
  23. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/init.py +3 -0
  24. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/makemigrations_cmd.py +13 -0
  25. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/migrate_cmd.py +24 -0
  26. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/migrations_cmd.py +14 -4
  27. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/revert_cmd.py +5 -0
  28. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/showmigrations_cmd.py +6 -3
  29. ferrum_orm-0.1.3/python/ferrum/cli/sqlmigrate_cmd.py +53 -0
  30. ferrum_orm-0.1.3/python/ferrum/config.py +243 -0
  31. ferrum_orm-0.1.3/python/ferrum/connection.py +567 -0
  32. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/drivers/__init__.py +10 -1
  33. ferrum_orm-0.1.3/python/ferrum/drivers/mssql.py +200 -0
  34. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/drivers/postgres.py +33 -8
  35. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/drivers/protocol.py +17 -3
  36. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/errors.py +43 -0
  37. ferrum_orm-0.1.3/python/ferrum/expressions.py +82 -0
  38. ferrum_orm-0.1.3/python/ferrum/ext/pgvector.py +238 -0
  39. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/__init__.py +18 -0
  40. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/introspect.py +81 -1
  41. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/ledger.py +48 -3
  42. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/loader.py +7 -0
  43. ferrum_orm-0.1.3/python/ferrum/migrations/operations.py +657 -0
  44. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/orchestrator.py +326 -15
  45. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/models.py +161 -24
  46. ferrum_orm-0.1.3/python/ferrum/observability.py +159 -0
  47. ferrum_orm-0.1.3/python/ferrum/queryset.py +2294 -0
  48. ferrum_orm-0.1.3/python/ferrum/registry.py +55 -0
  49. ferrum_orm-0.1.3/python/ferrum/relations.py +359 -0
  50. ferrum_orm-0.1.3/python/ferrum/runtime.py +188 -0
  51. ferrum_orm-0.1.3/python/ferrum/session.py +171 -0
  52. ferrum_orm-0.1.2/crates/ferrum-core/src/error.rs +0 -73
  53. ferrum_orm-0.1.2/crates/ferrum-core/src/ir/mod.rs +0 -152
  54. ferrum_orm-0.1.2/crates/ferrum-core/src/migrate/mod.rs +0 -72
  55. ferrum_orm-0.1.2/crates/ferrum-sql/src/dialect.rs +0 -94
  56. ferrum_orm-0.1.2/crates/ferrum-sql/src/emit.rs +0 -864
  57. ferrum_orm-0.1.2/python/ferrum/config.py +0 -104
  58. ferrum_orm-0.1.2/python/ferrum/connection.py +0 -292
  59. ferrum_orm-0.1.2/python/ferrum/ext/pgvector.py +0 -49
  60. ferrum_orm-0.1.2/python/ferrum/migrations/operations.py +0 -334
  61. ferrum_orm-0.1.2/python/ferrum/queryset.py +0 -1078
  62. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/LICENSE +0 -0
  63. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-core/Cargo.toml +0 -0
  64. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-core/src/lib.rs +0 -0
  65. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/crates/ferrum-sql/src/lib.rs +0 -0
  66. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/__init__.py +0 -0
  67. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/inspectdb_cmd.py +0 -0
  68. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/cli/resetdb_cmd.py +0 -0
  69. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/contrib/__init__.py +0 -0
  70. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/contrib/fastapi.py +0 -0
  71. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/drivers/mysql.py +0 -0
  72. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/drivers/sqlite.py +0 -0
  73. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/ext/__init__.py +0 -0
  74. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/hooks.py +0 -0
  75. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/base.py +0 -0
  76. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/drift.py +0 -0
  77. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/gates.py +0 -0
  78. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/migrations/tokens.py +0 -0
  79. {ferrum_orm-0.1.2 → ferrum_orm-0.1.3}/python/ferrum/py.typed +0 -0
@@ -223,7 +223,7 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
223
223
 
224
224
  [[package]]
225
225
  name = "ferrum-core"
226
- version = "0.1.2"
226
+ version = "0.1.3"
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.2"
237
+ version = "0.1.3"
238
238
  dependencies = [
239
239
  "ferrum-core",
240
240
  "serde",
@@ -243,23 +243,26 @@ dependencies = [
243
243
 
244
244
  [[package]]
245
245
  name = "ferrum-pyo3"
246
- version = "0.1.2"
246
+ version = "0.1.3"
247
247
  dependencies = [
248
248
  "ferrum-core",
249
249
  "ferrum-sql",
250
250
  "pyo3",
251
+ "rmp-serde",
251
252
  "serde_json",
252
253
  "thiserror",
253
254
  ]
254
255
 
255
256
  [[package]]
256
257
  name = "ferrum-sql"
257
- version = "0.1.2"
258
+ version = "0.1.3"
258
259
  dependencies = [
259
260
  "criterion",
260
261
  "ferrum-core",
261
262
  "proptest",
263
+ "rmp-serde",
262
264
  "serde",
265
+ "serde_json",
263
266
  "thiserror",
264
267
  ]
265
268
 
@@ -726,6 +729,25 @@ version = "0.8.11"
726
729
  source = "registry+https://github.com/rust-lang/crates.io-index"
727
730
  checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
728
731
 
732
+ [[package]]
733
+ name = "rmp"
734
+ version = "0.8.15"
735
+ source = "registry+https://github.com/rust-lang/crates.io-index"
736
+ checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c"
737
+ dependencies = [
738
+ "num-traits",
739
+ ]
740
+
741
+ [[package]]
742
+ name = "rmp-serde"
743
+ version = "1.3.1"
744
+ source = "registry+https://github.com/rust-lang/crates.io-index"
745
+ checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
746
+ dependencies = [
747
+ "rmp",
748
+ "serde",
749
+ ]
750
+
729
751
  [[package]]
730
752
  name = "rustix"
731
753
  version = "1.1.4"
@@ -3,7 +3,7 @@ members = ["crates/ferrum-core", "crates/ferrum-sql", "crates/ferrum-pyo3"]
3
3
  resolver = "2"
4
4
 
5
5
  [workspace.package]
6
- version = "0.1.2"
6
+ version = "0.1.3"
7
7
  edition = "2021"
8
8
  authors = ["Ferrum Contributors"]
9
9
  license = "Apache-2.0"
@@ -17,6 +17,9 @@ pyo3 = { version = "0.29", features = ["abi3-py311"] }
17
17
  # Serialization
18
18
  serde = { version = "1", features = ["derive"] }
19
19
  serde_json = "1"
20
+ # MessagePack wire format for the PyO3 boundary (always compiled; the Python
21
+ # `[msgpack]` extra gates only the runtime `msgpack` package + selection).
22
+ rmp-serde = "1"
20
23
 
21
24
  # Error handling
22
25
  thiserror = "2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ferrum-orm
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Framework :: AsyncIO
6
6
  Classifier: Intended Audience :: Developers
@@ -17,6 +17,8 @@ Requires-Dist: pydantic>=2.0
17
17
  Requires-Dist: ferrum-orm[pg] ; extra == 'all'
18
18
  Requires-Dist: ferrum-orm[mysql] ; extra == 'all'
19
19
  Requires-Dist: ferrum-orm[sqlite] ; extra == 'all'
20
+ Requires-Dist: ferrum-orm[mssql] ; extra == 'all'
21
+ Requires-Dist: ferrum-orm[msgpack] ; extra == 'all'
20
22
  Requires-Dist: ferrum-orm[cli] ; extra == 'all'
21
23
  Requires-Dist: ferrum-orm[dotenv] ; extra == 'all'
22
24
  Requires-Dist: typer>=0.12 ; extra == 'cli'
@@ -33,7 +35,10 @@ Requires-Dist: import-linter>=2 ; extra == 'dev'
33
35
  Requires-Dist: testcontainers[postgres]>=4 ; extra == 'dev'
34
36
  Requires-Dist: pip-audit>=2 ; extra == 'dev'
35
37
  Requires-Dist: python-dotenv>=1.0 ; extra == 'dotenv'
38
+ Requires-Dist: msgpack>=1.0 ; extra == 'msgpack'
39
+ Requires-Dist: aioodbc>=0.5 ; extra == 'mssql'
36
40
  Requires-Dist: asyncmy>=0.2 ; extra == 'mysql'
41
+ Requires-Dist: opentelemetry-api>=1.20 ; extra == 'otel'
37
42
  Requires-Dist: asyncpg>=0.29 ; extra == 'pg'
38
43
  Requires-Dist: aiosqlite>=0.19 ; extra == 'sqlite'
39
44
  Requires-Dist: uuid6>=2024.1 ; extra == 'uuid7'
@@ -42,13 +47,16 @@ Provides-Extra: cli
42
47
  Provides-Extra: dev
43
48
  Provides-Extra: dotenv
44
49
  Provides-Extra: fastapi
50
+ Provides-Extra: msgpack
51
+ Provides-Extra: mssql
45
52
  Provides-Extra: mysql
53
+ Provides-Extra: otel
46
54
  Provides-Extra: pg
47
55
  Provides-Extra: sqlite
48
56
  Provides-Extra: uuid7
49
57
  License-File: LICENSE
50
58
  Summary: Next-generation async ORM for Python with a Rust-powered core
51
- Keywords: orm,async,postgresql,mysql,sqlite,pydantic,rust
59
+ Keywords: orm,async,postgresql,mysql,sqlite,mssql,pydantic,rust
52
60
  License: Apache-2.0
53
61
  Requires-Python: >=3.11
54
62
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
@@ -83,7 +91,7 @@ Ferrum aims to provide all four.
83
91
  - Pydantic-first models
84
92
  - Django-inspired ORM experience
85
93
  - Rust-powered query engine
86
- - PostgreSQL-first architecture (MySQL and SQLite via optional extras)
94
+ - PostgreSQL-first architecture (MySQL, SQLite, and SQL Server via optional extras)
87
95
  - Type-safe query construction
88
96
  - Automatic migrations
89
97
  - High-performance result hydration
@@ -199,34 +207,41 @@ This allows Ferrum to maintain a Pythonic API without sacrificing performance.
199
207
 
200
208
  ## Roadmap
201
209
 
202
- ### v0.1
203
-
204
- - [ ] PostgreSQL support
205
- - [ ] Basic CRUD operations
206
- - [ ] Async query execution
207
- - [ ] Pydantic models
208
- - [ ] Query builder
209
- - [ ] Type-safe filters
210
-
211
- ### v0.2
212
-
213
- - [ ] Relationships
214
- - [x] Transactions
215
- - [ ] Query optimization
216
- - [ ] Bulk operations
217
-
218
- ### v0.3
219
-
220
- - [ ] Migrations
221
- - [ ] Schema diff engine
222
- - [ ] CLI tools
210
+ ### v0.1 (complete)
211
+
212
+ - [x] PostgreSQL support
213
+ - [x] Basic CRUD operations
214
+ - [x] Async query execution
215
+ - [x] Pydantic models
216
+ - [x] Query builder
217
+ - [x] Type-safe filters
218
+ - [x] Transactions and savepoints
219
+ - [x] Bulk operations (`bulk_create`, `bulk_update`, `bulk_delete`)
220
+ - [x] Migrations (schema diff, apply, revert, CLI)
221
+ - [x] Relationships (ForeignKey, OneToOne, ManyToMany)
222
+ - [x] pgvector KNN search and HNSW/IVFFLAT index DDL
223
+ - [x] Full-text search (TSVector / `plainto_tsquery`)
224
+ - [x] Observability hooks (Tier A/B/C)
225
+ - [x] CLI (`makemigrations`, `migrate`, `revert`, `showmigrations`, `inspectdb`, `resetdb`)
226
+
227
+ ### v0.2 (in progress)
228
+
229
+ - [x] Upsert API (`upsert`, `bulk_upsert` with conflict targets and `RETURNING`)
230
+ - [x] Composite primary keys
231
+ - [x] Array field types (`uuid[]`, `text[]`, scalar arrays)
232
+ - [x] JSONB operators (`__contains`, `__has_key`)
233
+ - [x] RLS / tenant session helpers (`set_config`, `tenant_session`)
234
+ - [x] `call_function` for allowlisted stored-procedure calls
235
+ - [x] Migration ops for extensions, RLS policies, and function DDL
236
+ - [x] pgvector similarity score projection (`vector_search` helper)
237
+ - [ ] Query optimization (deferred fields, prefetch tuning)
238
+ - [ ] Advanced relationship loading
223
239
 
224
240
  ### v1.0
225
241
 
226
242
  - [ ] Production-ready stability
227
- - [ ] Advanced relationships
228
- - [ ] Performance benchmarking
229
- - [ ] Full documentation
243
+ - [ ] Performance benchmarking suite
244
+ - [ ] Full documentation site
230
245
 
231
246
  ## Project Status
232
247
 
@@ -249,6 +264,12 @@ pip install 'ferrum-orm[mysql]'
249
264
  # SQLite + migrations CLI (testing / local dev)
250
265
  pip install 'ferrum-orm[sqlite,cli]'
251
266
 
267
+ # SQL Server (also needs a system ODBC driver, e.g. msodbcsql18)
268
+ pip install 'ferrum-orm[mssql]'
269
+
270
+ # Optional MessagePack wire format for the Python<->Rust boundary
271
+ pip install 'ferrum-orm[msgpack]'
272
+
252
273
  # Everything (all drivers + CLI + dotenv)
253
274
  pip install 'ferrum-orm[all]'
254
275
 
@@ -257,7 +278,19 @@ pip install ferrum-orm
257
278
  ```
258
279
 
259
280
  Bare `ferrum-orm` installs Pydantic and the Rust core only. Choose a driver extra
260
- (`pg`, `mysql`, or `sqlite`) before calling `ferrum.connect()`.
281
+ (`pg`, `mysql`, `sqlite`, or `mssql`) before calling `ferrum.connect()`.
282
+
283
+ MySQL, SQLite, and SQL Server are **thin-parity** backends: they support core CRUD
284
+ and migrations but not transactions, upsert, `bulk_update`, RLS, or pgvector
285
+ (PostgreSQL only). SQL Server connects via `aioodbc`/`pyodbc` and requires a system
286
+ ODBC driver such as `msodbcsql18`; DSNs use the `mssql://` or `sqlserver://` scheme.
287
+
288
+ ### Wire format (advanced)
289
+
290
+ The Python↔Rust IR/hydration boundary defaults to JSON. Installing the `msgpack`
291
+ extra lets you switch it to MessagePack, selected via the `FERRUM_WIRE_FORMAT`
292
+ environment variable (`json` | `msgpack`) or the `[ferrum] wire_format` key in
293
+ `ferrum.toml` / `pyproject.toml`. JSON remains the default; MessagePack is opt-in.
261
294
 
262
295
  From source, build the native extension with `maturin develop` (or `mise run dev`).
263
296
 
@@ -271,7 +304,8 @@ Runnable samples live under [`examples/`](examples/):
271
304
 
272
305
  ## Contributing
273
306
 
274
- Contributions are welcome.
307
+ Contributions are welcome. Start with [`CONTRIBUTING.md`](CONTRIBUTING.md) for local setup,
308
+ scoped verification, architecture rules, and pull request expectations.
275
309
 
276
310
  ## License
277
311
 
@@ -24,7 +24,7 @@ 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 (MySQL and SQLite via optional extras)
27
+ - PostgreSQL-first architecture (MySQL, SQLite, and SQL Server via optional extras)
28
28
  - Type-safe query construction
29
29
  - Automatic migrations
30
30
  - High-performance result hydration
@@ -140,34 +140,41 @@ This allows Ferrum to maintain a Pythonic API without sacrificing performance.
140
140
 
141
141
  ## Roadmap
142
142
 
143
- ### v0.1
144
-
145
- - [ ] PostgreSQL support
146
- - [ ] Basic CRUD operations
147
- - [ ] Async query execution
148
- - [ ] Pydantic models
149
- - [ ] Query builder
150
- - [ ] Type-safe filters
151
-
152
- ### v0.2
153
-
154
- - [ ] Relationships
155
- - [x] Transactions
156
- - [ ] Query optimization
157
- - [ ] Bulk operations
158
-
159
- ### v0.3
160
-
161
- - [ ] Migrations
162
- - [ ] Schema diff engine
163
- - [ ] CLI tools
143
+ ### v0.1 (complete)
144
+
145
+ - [x] PostgreSQL support
146
+ - [x] Basic CRUD operations
147
+ - [x] Async query execution
148
+ - [x] Pydantic models
149
+ - [x] Query builder
150
+ - [x] Type-safe filters
151
+ - [x] Transactions and savepoints
152
+ - [x] Bulk operations (`bulk_create`, `bulk_update`, `bulk_delete`)
153
+ - [x] Migrations (schema diff, apply, revert, CLI)
154
+ - [x] Relationships (ForeignKey, OneToOne, ManyToMany)
155
+ - [x] pgvector KNN search and HNSW/IVFFLAT index DDL
156
+ - [x] Full-text search (TSVector / `plainto_tsquery`)
157
+ - [x] Observability hooks (Tier A/B/C)
158
+ - [x] CLI (`makemigrations`, `migrate`, `revert`, `showmigrations`, `inspectdb`, `resetdb`)
159
+
160
+ ### v0.2 (in progress)
161
+
162
+ - [x] Upsert API (`upsert`, `bulk_upsert` with conflict targets and `RETURNING`)
163
+ - [x] Composite primary keys
164
+ - [x] Array field types (`uuid[]`, `text[]`, scalar arrays)
165
+ - [x] JSONB operators (`__contains`, `__has_key`)
166
+ - [x] RLS / tenant session helpers (`set_config`, `tenant_session`)
167
+ - [x] `call_function` for allowlisted stored-procedure calls
168
+ - [x] Migration ops for extensions, RLS policies, and function DDL
169
+ - [x] pgvector similarity score projection (`vector_search` helper)
170
+ - [ ] Query optimization (deferred fields, prefetch tuning)
171
+ - [ ] Advanced relationship loading
164
172
 
165
173
  ### v1.0
166
174
 
167
175
  - [ ] Production-ready stability
168
- - [ ] Advanced relationships
169
- - [ ] Performance benchmarking
170
- - [ ] Full documentation
176
+ - [ ] Performance benchmarking suite
177
+ - [ ] Full documentation site
171
178
 
172
179
  ## Project Status
173
180
 
@@ -190,6 +197,12 @@ pip install 'ferrum-orm[mysql]'
190
197
  # SQLite + migrations CLI (testing / local dev)
191
198
  pip install 'ferrum-orm[sqlite,cli]'
192
199
 
200
+ # SQL Server (also needs a system ODBC driver, e.g. msodbcsql18)
201
+ pip install 'ferrum-orm[mssql]'
202
+
203
+ # Optional MessagePack wire format for the Python<->Rust boundary
204
+ pip install 'ferrum-orm[msgpack]'
205
+
193
206
  # Everything (all drivers + CLI + dotenv)
194
207
  pip install 'ferrum-orm[all]'
195
208
 
@@ -198,7 +211,19 @@ pip install ferrum-orm
198
211
  ```
199
212
 
200
213
  Bare `ferrum-orm` installs Pydantic and the Rust core only. Choose a driver extra
201
- (`pg`, `mysql`, or `sqlite`) before calling `ferrum.connect()`.
214
+ (`pg`, `mysql`, `sqlite`, or `mssql`) before calling `ferrum.connect()`.
215
+
216
+ MySQL, SQLite, and SQL Server are **thin-parity** backends: they support core CRUD
217
+ and migrations but not transactions, upsert, `bulk_update`, RLS, or pgvector
218
+ (PostgreSQL only). SQL Server connects via `aioodbc`/`pyodbc` and requires a system
219
+ ODBC driver such as `msodbcsql18`; DSNs use the `mssql://` or `sqlserver://` scheme.
220
+
221
+ ### Wire format (advanced)
222
+
223
+ The Python↔Rust IR/hydration boundary defaults to JSON. Installing the `msgpack`
224
+ extra lets you switch it to MessagePack, selected via the `FERRUM_WIRE_FORMAT`
225
+ environment variable (`json` | `msgpack`) or the `[ferrum] wire_format` key in
226
+ `ferrum.toml` / `pyproject.toml`. JSON remains the default; MessagePack is opt-in.
202
227
 
203
228
  From source, build the native extension with `maturin develop` (or `mise run dev`).
204
229
 
@@ -212,7 +237,8 @@ Runnable samples live under [`examples/`](examples/):
212
237
 
213
238
  ## Contributing
214
239
 
215
- Contributions are welcome.
240
+ Contributions are welcome. Start with [`CONTRIBUTING.md`](CONTRIBUTING.md) for local setup,
241
+ scoped verification, architecture rules, and pull request expectations.
216
242
 
217
243
  ## License
218
244
 
@@ -47,6 +47,7 @@ fn bench_metadata() -> ModelMetadata {
47
47
  },
48
48
  ],
49
49
  pk_index: 0,
50
+ pk_fields: vec![0],
50
51
  }
51
52
  }
52
53