ferrum-orm 0.1.1__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 (83) hide show
  1. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/Cargo.lock +38 -46
  2. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/Cargo.toml +5 -2
  3. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/PKG-INFO +67 -29
  4. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/README.md +57 -27
  5. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-core/Cargo.toml +1 -0
  6. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-core/benches/hydrate.rs +1 -0
  7. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-core/src/compile/mod.rs +224 -29
  8. ferrum_orm-0.1.3/crates/ferrum-core/src/error.rs +111 -0
  9. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-core/src/hydrate/mod.rs +1 -0
  10. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-core/src/ir/metadata.rs +30 -1
  11. ferrum_orm-0.1.3/crates/ferrum-core/src/ir/mod.rs +276 -0
  12. ferrum_orm-0.1.3/crates/ferrum-core/src/migrate/mod.rs +91 -0
  13. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-pyo3/Cargo.toml +2 -0
  14. ferrum_orm-0.1.3/crates/ferrum-pyo3/src/lib.rs +377 -0
  15. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-sql/Cargo.toml +4 -0
  16. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-sql/benches/compile.rs +5 -0
  17. ferrum_orm-0.1.3/crates/ferrum-sql/src/dialect.rs +143 -0
  18. ferrum_orm-0.1.3/crates/ferrum-sql/src/emit.rs +1767 -0
  19. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/pyproject.toml +12 -4
  20. ferrum_orm-0.1.3/python/ferrum/__init__.py +112 -0
  21. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/_native.pyi +34 -1
  22. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/app.py +20 -0
  23. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/bootstrap.py +3 -2
  24. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/init.py +3 -0
  25. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/inspectdb_cmd.py +65 -18
  26. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/makemigrations_cmd.py +13 -0
  27. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/migrate_cmd.py +68 -29
  28. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/migrations_cmd.py +14 -4
  29. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/revert_cmd.py +45 -22
  30. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/showmigrations_cmd.py +6 -3
  31. ferrum_orm-0.1.3/python/ferrum/cli/sqlmigrate_cmd.py +53 -0
  32. ferrum_orm-0.1.3/python/ferrum/config.py +243 -0
  33. ferrum_orm-0.1.3/python/ferrum/connection.py +567 -0
  34. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/drivers/__init__.py +10 -1
  35. ferrum_orm-0.1.3/python/ferrum/drivers/mssql.py +200 -0
  36. ferrum_orm-0.1.3/python/ferrum/drivers/postgres.py +221 -0
  37. ferrum_orm-0.1.3/python/ferrum/drivers/protocol.py +51 -0
  38. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/errors.py +114 -0
  39. ferrum_orm-0.1.3/python/ferrum/expressions.py +82 -0
  40. ferrum_orm-0.1.3/python/ferrum/ext/pgvector.py +238 -0
  41. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/__init__.py +18 -0
  42. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/introspect.py +81 -1
  43. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/ledger.py +48 -3
  44. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/loader.py +7 -0
  45. ferrum_orm-0.1.3/python/ferrum/migrations/operations.py +657 -0
  46. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/orchestrator.py +359 -18
  47. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/models.py +197 -28
  48. ferrum_orm-0.1.3/python/ferrum/observability.py +159 -0
  49. ferrum_orm-0.1.3/python/ferrum/queryset.py +2294 -0
  50. ferrum_orm-0.1.3/python/ferrum/registry.py +55 -0
  51. ferrum_orm-0.1.3/python/ferrum/relations.py +359 -0
  52. ferrum_orm-0.1.3/python/ferrum/runtime.py +188 -0
  53. ferrum_orm-0.1.3/python/ferrum/session.py +171 -0
  54. ferrum_orm-0.1.1/crates/ferrum-core/src/error.rs +0 -73
  55. ferrum_orm-0.1.1/crates/ferrum-core/src/ir/mod.rs +0 -152
  56. ferrum_orm-0.1.1/crates/ferrum-core/src/migrate/mod.rs +0 -72
  57. ferrum_orm-0.1.1/crates/ferrum-pyo3/src/lib.rs +0 -252
  58. ferrum_orm-0.1.1/crates/ferrum-sql/src/dialect.rs +0 -94
  59. ferrum_orm-0.1.1/crates/ferrum-sql/src/emit.rs +0 -864
  60. ferrum_orm-0.1.1/python/ferrum/__init__.py +0 -63
  61. ferrum_orm-0.1.1/python/ferrum/config.py +0 -104
  62. ferrum_orm-0.1.1/python/ferrum/connection.py +0 -169
  63. ferrum_orm-0.1.1/python/ferrum/drivers/postgres.py +0 -121
  64. ferrum_orm-0.1.1/python/ferrum/drivers/protocol.py +0 -27
  65. ferrum_orm-0.1.1/python/ferrum/ext/pgvector.py +0 -49
  66. ferrum_orm-0.1.1/python/ferrum/migrations/operations.py +0 -334
  67. ferrum_orm-0.1.1/python/ferrum/queryset.py +0 -1074
  68. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/LICENSE +0 -0
  69. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-core/src/lib.rs +0 -0
  70. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/crates/ferrum-sql/src/lib.rs +0 -0
  71. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/__init__.py +0 -0
  72. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/cli/resetdb_cmd.py +0 -0
  73. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/contrib/__init__.py +0 -0
  74. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/contrib/fastapi.py +0 -0
  75. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/drivers/mysql.py +0 -0
  76. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/drivers/sqlite.py +0 -0
  77. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/ext/__init__.py +0 -0
  78. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/hooks.py +0 -0
  79. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/base.py +0 -0
  80. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/drift.py +0 -0
  81. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/gates.py +0 -0
  82. {ferrum_orm-0.1.1 → ferrum_orm-0.1.3}/python/ferrum/migrations/tokens.py +0 -0
  83. {ferrum_orm-0.1.1 → 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.1"
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.1"
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.1"
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.1"
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
 
@@ -380,15 +383,6 @@ dependencies = [
380
383
  "serde_core",
381
384
  ]
382
385
 
383
- [[package]]
384
- name = "indoc"
385
- version = "2.0.7"
386
- source = "registry+https://github.com/rust-lang/crates.io-index"
387
- checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
388
- dependencies = [
389
- "rustversion",
390
- ]
391
-
392
386
  [[package]]
393
387
  name = "is-terminal"
394
388
  version = "0.4.17"
@@ -456,15 +450,6 @@ version = "2.8.2"
456
450
  source = "registry+https://github.com/rust-lang/crates.io-index"
457
451
  checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
458
452
 
459
- [[package]]
460
- name = "memoffset"
461
- version = "0.9.1"
462
- source = "registry+https://github.com/rust-lang/crates.io-index"
463
- checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
464
- dependencies = [
465
- "autocfg",
466
- ]
467
-
468
453
  [[package]]
469
454
  name = "num-traits"
470
455
  version = "0.2.19"
@@ -575,37 +560,32 @@ dependencies = [
575
560
 
576
561
  [[package]]
577
562
  name = "pyo3"
578
- version = "0.22.6"
563
+ version = "0.29.0"
579
564
  source = "registry+https://github.com/rust-lang/crates.io-index"
580
- checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
565
+ checksum = "cd274650b21d4bfc26a0a47587962c1edb425f69287324355cd040c3ea66071c"
581
566
  dependencies = [
582
- "cfg-if",
583
- "indoc",
584
567
  "libc",
585
- "memoffset",
586
568
  "once_cell",
587
569
  "portable-atomic",
588
570
  "pyo3-build-config",
589
571
  "pyo3-ffi",
590
572
  "pyo3-macros",
591
- "unindent",
592
573
  ]
593
574
 
594
575
  [[package]]
595
576
  name = "pyo3-build-config"
596
- version = "0.22.6"
577
+ version = "0.29.0"
597
578
  source = "registry+https://github.com/rust-lang/crates.io-index"
598
- checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
579
+ checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078"
599
580
  dependencies = [
600
- "once_cell",
601
581
  "target-lexicon",
602
582
  ]
603
583
 
604
584
  [[package]]
605
585
  name = "pyo3-ffi"
606
- version = "0.22.6"
586
+ version = "0.29.0"
607
587
  source = "registry+https://github.com/rust-lang/crates.io-index"
608
- checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
588
+ checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b"
609
589
  dependencies = [
610
590
  "libc",
611
591
  "pyo3-build-config",
@@ -613,9 +593,9 @@ dependencies = [
613
593
 
614
594
  [[package]]
615
595
  name = "pyo3-macros"
616
- version = "0.22.6"
596
+ version = "0.29.0"
617
597
  source = "registry+https://github.com/rust-lang/crates.io-index"
618
- checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
598
+ checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771"
619
599
  dependencies = [
620
600
  "proc-macro2",
621
601
  "pyo3-macros-backend",
@@ -625,13 +605,12 @@ dependencies = [
625
605
 
626
606
  [[package]]
627
607
  name = "pyo3-macros-backend"
628
- version = "0.22.6"
608
+ version = "0.29.0"
629
609
  source = "registry+https://github.com/rust-lang/crates.io-index"
630
- checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
610
+ checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362"
631
611
  dependencies = [
632
612
  "heck",
633
613
  "proc-macro2",
634
- "pyo3-build-config",
635
614
  "quote",
636
615
  "syn",
637
616
  ]
@@ -750,6 +729,25 @@ version = "0.8.11"
750
729
  source = "registry+https://github.com/rust-lang/crates.io-index"
751
730
  checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
752
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
+
753
751
  [[package]]
754
752
  name = "rustix"
755
753
  version = "1.1.4"
@@ -858,9 +856,9 @@ dependencies = [
858
856
 
859
857
  [[package]]
860
858
  name = "target-lexicon"
861
- version = "0.12.16"
859
+ version = "0.13.5"
862
860
  source = "registry+https://github.com/rust-lang/crates.io-index"
863
- checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
861
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
864
862
 
865
863
  [[package]]
866
864
  name = "tempfile"
@@ -923,12 +921,6 @@ version = "0.2.6"
923
921
  source = "registry+https://github.com/rust-lang/crates.io-index"
924
922
  checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
925
923
 
926
- [[package]]
927
- name = "unindent"
928
- version = "0.2.4"
929
- source = "registry+https://github.com/rust-lang/crates.io-index"
930
- checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
931
-
932
924
  [[package]]
933
925
  name = "wait-timeout"
934
926
  version = "0.2.1"
@@ -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.1"
6
+ version = "0.1.3"
7
7
  edition = "2021"
8
8
  authors = ["Ferrum Contributors"]
9
9
  license = "Apache-2.0"
@@ -12,11 +12,14 @@ rust-version = "1.85"
12
12
 
13
13
  [workspace.dependencies]
14
14
  # PyO3 — only ferrum-pyo3 depends on this; declared here to pin the version
15
- pyo3 = { version = "0.22", features = ["abi3-py311"] }
15
+ pyo3 = { version = "0.29", features = ["abi3-py311"] }
16
16
 
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.1
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
@@ -115,6 +123,10 @@ users = await (
115
123
  .limit(10)
116
124
  .all(conn)
117
125
  )
126
+
127
+ async with conn.transaction() as tx:
128
+ user = await User.objects.create(tx, email="jane@example.com")
129
+ await AuditLog.objects.create(tx, user_id=user.id, action="signup")
118
130
  ```
119
131
 
120
132
  ---
@@ -195,34 +207,41 @@ This allows Ferrum to maintain a Pythonic API without sacrificing performance.
195
207
 
196
208
  ## Roadmap
197
209
 
198
- ### v0.1
199
-
200
- - [ ] PostgreSQL support
201
- - [ ] Basic CRUD operations
202
- - [ ] Async query execution
203
- - [ ] Pydantic models
204
- - [ ] Query builder
205
- - [ ] Type-safe filters
206
-
207
- ### v0.2
208
-
209
- - [ ] Relationships
210
- - [ ] Transactions
211
- - [ ] Query optimization
212
- - [ ] Bulk operations
213
-
214
- ### v0.3
215
-
216
- - [ ] Migrations
217
- - [ ] Schema diff engine
218
- - [ ] 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
219
239
 
220
240
  ### v1.0
221
241
 
222
242
  - [ ] Production-ready stability
223
- - [ ] Advanced relationships
224
- - [ ] Performance benchmarking
225
- - [ ] Full documentation
243
+ - [ ] Performance benchmarking suite
244
+ - [ ] Full documentation site
226
245
 
227
246
  ## Project Status
228
247
 
@@ -245,6 +264,12 @@ pip install 'ferrum-orm[mysql]'
245
264
  # SQLite + migrations CLI (testing / local dev)
246
265
  pip install 'ferrum-orm[sqlite,cli]'
247
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
+
248
273
  # Everything (all drivers + CLI + dotenv)
249
274
  pip install 'ferrum-orm[all]'
250
275
 
@@ -253,7 +278,19 @@ pip install ferrum-orm
253
278
  ```
254
279
 
255
280
  Bare `ferrum-orm` installs Pydantic and the Rust core only. Choose a driver extra
256
- (`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.
257
294
 
258
295
  From source, build the native extension with `maturin develop` (or `mise run dev`).
259
296
 
@@ -267,7 +304,8 @@ Runnable samples live under [`examples/`](examples/):
267
304
 
268
305
  ## Contributing
269
306
 
270
- 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.
271
309
 
272
310
  ## License
273
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
@@ -56,6 +56,10 @@ users = await (
56
56
  .limit(10)
57
57
  .all(conn)
58
58
  )
59
+
60
+ async with conn.transaction() as tx:
61
+ user = await User.objects.create(tx, email="jane@example.com")
62
+ await AuditLog.objects.create(tx, user_id=user.id, action="signup")
59
63
  ```
60
64
 
61
65
  ---
@@ -136,34 +140,41 @@ This allows Ferrum to maintain a Pythonic API without sacrificing performance.
136
140
 
137
141
  ## Roadmap
138
142
 
139
- ### v0.1
140
-
141
- - [ ] PostgreSQL support
142
- - [ ] Basic CRUD operations
143
- - [ ] Async query execution
144
- - [ ] Pydantic models
145
- - [ ] Query builder
146
- - [ ] Type-safe filters
147
-
148
- ### v0.2
149
-
150
- - [ ] Relationships
151
- - [ ] Transactions
152
- - [ ] Query optimization
153
- - [ ] Bulk operations
154
-
155
- ### v0.3
156
-
157
- - [ ] Migrations
158
- - [ ] Schema diff engine
159
- - [ ] 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
160
172
 
161
173
  ### v1.0
162
174
 
163
175
  - [ ] Production-ready stability
164
- - [ ] Advanced relationships
165
- - [ ] Performance benchmarking
166
- - [ ] Full documentation
176
+ - [ ] Performance benchmarking suite
177
+ - [ ] Full documentation site
167
178
 
168
179
  ## Project Status
169
180
 
@@ -186,6 +197,12 @@ pip install 'ferrum-orm[mysql]'
186
197
  # SQLite + migrations CLI (testing / local dev)
187
198
  pip install 'ferrum-orm[sqlite,cli]'
188
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
+
189
206
  # Everything (all drivers + CLI + dotenv)
190
207
  pip install 'ferrum-orm[all]'
191
208
 
@@ -194,7 +211,19 @@ pip install ferrum-orm
194
211
  ```
195
212
 
196
213
  Bare `ferrum-orm` installs Pydantic and the Rust core only. Choose a driver extra
197
- (`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.
198
227
 
199
228
  From source, build the native extension with `maturin develop` (or `mise run dev`).
200
229
 
@@ -208,7 +237,8 @@ Runnable samples live under [`examples/`](examples/):
208
237
 
209
238
  ## Contributing
210
239
 
211
- 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.
212
242
 
213
243
  ## License
214
244
 
@@ -1,5 +1,6 @@
1
1
  [package]
2
2
  name = "ferrum-core"
3
+ publish = false
3
4
  version.workspace = true
4
5
  edition.workspace = true
5
6
  authors.workspace = true
@@ -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