ferro-orm 0.17.1__tar.gz → 0.19.0__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.
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/AGENTS.md +50 -2
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/CHANGELOG.md +46 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/CONTEXT.md +23 -3
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/Cargo.lock +116 -125
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/Cargo.toml +1 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/PKG-INFO +1 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-ddl-lowering/src/lib.rs +1113 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/emit.rs +99 -3
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/lib.rs +142 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/tests.rs +477 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-schema-ir/src/lib.rs +143 -0
- ferro_orm-0.19.0/docs/adr/0011-label-addition-update-gated-append-only.md +65 -0
- ferro_orm-0.19.0/docs/adr/0012-table-checks-are-lambdas.md +12 -0
- ferro_orm-0.19.0/docs/adr/0013-table-check-reconciliation.md +12 -0
- ferro_orm-0.19.0/docs/adr/0014-table-checks-sqlite-create-only.md +11 -0
- ferro_orm-0.19.0/docs/adr/0015-table-check-body-drift.md +11 -0
- ferro_orm-0.19.0/docs/adr/0016-check-predicates-literals-only.md +11 -0
- ferro_orm-0.19.0/docs/examples/table_checks.py +45 -0
- ferro_orm-0.19.0/docs/examples/table_checks_annotated.py +42 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/exceptions.md +18 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/migrations.md +78 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/models-and-fields.md +32 -0
- ferro_orm-0.19.0/docs/solutions/issues/pg18-restrict-sqlstate-23001.md +33 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/pyproject.toml +1 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/errors.rs +87 -7
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/__init__.py +2 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_core.pyi +72 -1
- ferro_orm-0.19.0/src/ferro/checks.py +609 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/exceptions.py +6 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/ir/compiler.py +55 -0
- ferro_orm-0.19.0/src/ferro/migrations/alembic.py +664 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/models.py +12 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/introspect.rs +367 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/lib.rs +8 -1
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/migrate.rs +161 -7
- ferro_orm-0.19.0/src/naming_ffi.rs +241 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/schema.rs +11 -3
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/state.rs +1 -0
- ferro_orm-0.19.0/tests/test_check_predicate_dialect.py +348 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_cross_emitter_parity.py +20 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_exception_mapping.py +65 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_generation_counter_dirty_tracking.py +2 -10
- ferro_orm-0.19.0/tests/test_label_addition.py +380 -0
- ferro_orm-0.19.0/tests/test_live_table_checks.py +74 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_naming_single_source.py +19 -0
- ferro_orm-0.19.0/tests/test_table_check_orphans.py +546 -0
- ferro_orm-0.19.0/tests/test_table_check_rebuild.py +532 -0
- ferro_orm-0.19.0/tests/test_table_check_reconcile.py +514 -0
- ferro_orm-0.19.0/tests/test_table_checks.py +599 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/uv.lock +1 -1
- ferro_orm-0.17.1/src/ferro/migrations/alembic.py +0 -273
- ferro_orm-0.17.1/src/naming_ffi.rs +0 -92
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/PERMISSIONS.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/PYPI_CHECKLIST.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/PYPI_SETUP.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/generated/wheels.generated.yml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/pull_request_template.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/ci.yml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/packaging-smoke.yml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/publish-docs.yml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/publish.yml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.github/workflows/release.yml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.gitignore +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.pre-commit-config.yaml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/.python-version +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/CONTRIBUTING.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/LICENSE +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/README.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/README.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/__init__.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/__main__.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/backends.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/baselines/postgres.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/baselines/sqlite.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/compare.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/harness.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/model.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/benchmarks/run.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-ddl-lowering/Cargo.toml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/Cargo.toml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-migrate/src/order.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/crates/ferro-schema-ir/Cargo.toml +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0001-resolved-epoch-registration.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0002-unified-column-fact-derivation.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0003-path-blind-db-type-validation.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0004-jsonb-postgres-only-canonical.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0005-jsonb-default-on-postgres.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0006-relation-traversal-inner-joins.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0007-materialization-plan-complete-instances.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0007-reverse-relations-tested-not-traversed.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0008-populated-relations-include.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0008-predicate-negation-uniform-not.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0009-aggregate-projections-derived-grouping.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/adr/0010-create-pass-owns-only-missing-tables.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/agents/domain.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/agents/issue-tracker.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/agents/triage-labels.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/architecture-review-2026-07-08.html +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-04-29-named-connections-role-routing-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-08-typed-query-predicates-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-13-configurable-column-storage-types-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-14-autogenerate-support-for-db-type-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-05-25-annotated-strenum-cold-hydration-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-24-ir-p8-119-wire-automigrate-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-25-ir-p8-120-parity-gate-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-26-ir-p8.5-140-shared-lowering-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-26-ir-p8.5-143-db-type-drop-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-26-ir-p8.5-144-reconcile-indexes-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-28-ir-p8.5-141-single-schema-ir-producer-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-29-ir-p8.6-146-dialect-enum-unification-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-29-ir-p8.6-153-create-path-ir-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-30-ir-p8.6-155-deferred-annotations-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-06-30-ir-p8.6-158-check-renderer-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-01-ir-p8.6-154-datetime-tz-coarseness-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-01-ir-p8.6-162-typed-save-bind-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-01-ir-p8.6-165-blob-introspection-false-positive-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-02-ff-c1-codec-plan-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/brainstorms/2026-07-06-upgrade-guide-consolidation-requirements.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/aggregations.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/aggregations_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/existence_tests.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/existence_tests_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/multiple_databases.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/mutations.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/pagination.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/partial_selects.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/partial_selects_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/populated_relations.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/populated_relations_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/predicates.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/predicates_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/quickstart.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/quickstart_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/raw_sql.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/relationships.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/relationships_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/soft_deletes.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/soft_deletes_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/testing_conftest.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/timestamps.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/timestamps_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/transactions.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/traversal.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/examples/traversal_annotated.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/connection.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/fields.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/migrations.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/model.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/queries.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/raw-sql.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/relationships.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/api/transactions.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/changelog.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/architecture.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/backends.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/identity-map.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/performance.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/query-typing.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/concepts/type-safety.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/contributing.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/faq.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/getting-started/installation.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/getting-started/next-steps.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/getting-started/quickstart.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/aggregations.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/connections.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/mutations.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/queries.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/raw-sql.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/relationships.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/guide/transactions.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/migrate-from-sqlalchemy.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/multiple-databases.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/pagination.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/soft-deletes.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/testing.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/timestamps.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/howto/upgrade-guide.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/index.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/roadmap.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/stylesheets/extra.css +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/pages/why-ferro.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-04-24-001-refactor-multi-db-backend-architecture-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-04-29-001-typed-null-binds-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-04-29-002-feat-named-connections-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-07-001-refactor-generic-model-connection-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-08-001-feat-typed-query-predicates-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-13-001-feat-configurable-column-storage-types-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-05-25-001-fix-annotated-strenum-cold-hydration-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-19-001-ir-first-roadmap.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-24-001-feat-ir-p8-119-wire-automigrate-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-25-001-feat-ir-p8-120-parity-gate-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-26-001-feat-ir-p8.5-140-shared-lowering-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-26-002-feat-ir-p8.5-143-db-type-drop-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-26-003-feat-ir-p8.5-144-reconcile-indexes-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-28-001-feat-ir-p8.5-141-single-schema-ir-producer-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-29-001-refactor-ir-p8.6-153-create-path-unification-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-29-002-refactor-ir-p8.6-146-dialect-enum-unification-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-30-001-refactor-ir-p8.6-158-check-renderer-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-06-30-002-fix-ir-p8.6-155-deferred-annotations-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-01-001-feat-ir-p8.6-162-typed-save-bind-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-01-002-fix-ir-p8.6-154-datetime-tz-coarseness-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-01-003-fix-ir-p8.6-165-blob-introspection-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-001-fable-fixes-roadmap.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-002-feat-ff-a-172-typed-exceptions-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-003-ff-c-native-decode-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-004-ff-c-c2-catalog-cache-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-005-ff-d-identity-routing-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-02-006-ff-d-identity-routing-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-03-007-ff-e-registry-identity-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-03-008-ff-e-registry-identity-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-009-ff-f-query-builder-1.0-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-010-ff-f-query-builder-1.0-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-011-ff-g-hardening-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-012-ff-g-hardening-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-013-ff-g2-operations-dedup-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-014-ff-g2-operations-dedup-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-06-015-docs-upgrade-guide-consolidation-plan.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/2026-07-18-016-existence-tests-design.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/ir-first-migration-guide.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/plans/ir-first-release-checklist.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/rfc/ir-contracts-v1.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/README.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/architecture-patterns/ir-first-lowering-consolidation-audit.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/architecture-patterns/ir-first-merge-readiness-review.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/pydantic-slots-missing-after-ferro-hydration.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/python-3.14-deferred-annotation-typeerror-swallow.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sa-pk-column-nullable-divergence.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sa-vs-rust-unique-constraint-shape.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/self-fk-evicts-component-from-create-order.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sqlite-integer-decimal-hydrates-as-none.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/sqlite-null-hydrates-as-int-zero.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/issues/typed-where-null-panics-is-null.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/configurable-column-storage-types.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/cross-emitter-ddl-parity.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/ddl-on-live-engine.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/derived-type-and-naming-decision-table.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/foreign-key-index.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/index-unique-redundancy.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/ir-invariants.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/persistence-state.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/shadow-fk-columns.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/sqlite-alembic-reconnect-hydration-tests.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/docs/solutions/patterns/typed-null-binds.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/justfile +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/scripts/demo_queries.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/scripts/demo_queries_pre_v012.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/backend.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/codec.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/codec_plan.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/connection.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_annotation_utils.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_bind_payload.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_deprecations.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/_shadow_fk_types.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/base.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/columns.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/composite_indexes.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/composite_uniques.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/fields.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/ir/__init__.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/metaclass.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/migrations/__init__.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/py.typed +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/__init__.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/builder.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/nodes.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/rows.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/query/wire.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/raw.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/registry.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/relations/__init__.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/relations/descriptors.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/session.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/ferro/state.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/hydration.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/operations.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/query.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/src/schema_bind.rs +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/__init__.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/conftest.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/db_backends.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/README.md +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/codec_registry_core_v1.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_account_exists_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_account_scoped_exists_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_owner_nested_exists_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_owner_not_exists_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_aggregate_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_global_aggregate_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_include_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_left_join_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_record_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_traversal_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_transaction_traversed_record_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_compound_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_m2m_exists_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_not_compound_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/query_user_not_leaf_v7.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/schema_invoice_baseline_v1.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/schema_phase1_fixture_models_v1.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/fixtures/ir_vectors/schema_raw_str_pk_autoincrement_v1.json +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/bad_includes.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/bad_predicates.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/bad_projections.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/good_includes.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/good_predicates.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/static_fixtures/good_projections.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_aggregation.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_autogenerate.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_bridge.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_db_type.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_nullability.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_alembic_type_mapping.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_annotation_utils.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_auto_migrate.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_bulk_create_chunking.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_bulk_install.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_bulk_update.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_catalog_cache.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_codec_plan.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_column_specs.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_compiled_query.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_composite_index.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_composite_unique.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_connection.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_connection_redaction.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_constraints.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_crud.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_backends.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_cross_emitter_parity.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_integration.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_typing.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_db_type_validation.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_deletion.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_deprecations.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_docs_examples.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_documentation_features.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_enum_cold_hydration.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_exceptions.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_field_wrapper.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_fk_target_pk.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_global_aggregates.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_grouped_aggregates.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_helpers.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_hydration.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_hydration_equivalence.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_memory.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_refresh.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_scoped_invalidation.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_identity_weakref.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_import_budget.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_include.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_ir_vectors_contract.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_metaclass_internals.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_metadata.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_migrate_plan.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_model_identity.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_models.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_mutation_pagination_guard.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_named_connections_integration.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_negation.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_one_to_one.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_operation_seam_sync.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_partial_selects.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_primary_key_facts.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_provisional_import.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_builder.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_column_validation.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_exists.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_immutability.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_joins.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_typing.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_query_wire_vectors.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_raw_sql.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_refresh.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_registry_entrypoints.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_registry_owner.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_relation_specs.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_relationship_engine.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_relationship_resolution_errors.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_route_single_site.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_routing_errors.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_save_pk_edges.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_save_semantics.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema_constraints.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema_db_type_metadata.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_schema_enum_annotations.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_session.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_shadow_fk_types.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_sqlite_alembic_reconnect_hydration.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_static_contracts.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_string_search.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_structural_types.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_temporal_types.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_transactions.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_traversed_projection.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_typed_null_binds.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/tests/test_typed_save_bind.py +0 -0
- {ferro_orm-0.17.1 → ferro_orm-0.19.0}/zensical.toml +0 -0
|
@@ -46,10 +46,58 @@ For a single model, every emitter must agree on:
|
|
|
46
46
|
`docs/solutions/patterns/derived-type-and-naming-decision-table.md`.
|
|
47
47
|
7. **Primary key constraint names** — when explicitly named.
|
|
48
48
|
8. **Check constraint names** — `ck_<table>_<col>` for the single-column
|
|
49
|
-
`db_check=True` constraint;
|
|
50
|
-
|
|
49
|
+
`db_check=True` constraint; `ck_<table>_<suffix>` for table checks declared
|
|
50
|
+
in `__ferro_checks__`. Column checks use `_ddl_check_constraint_name`
|
|
51
|
+
(Python) and `db_check_constraint_name` (Rust); table checks use
|
|
52
|
+
`_ddl_table_check_constraint_name` (Python) and
|
|
53
|
+
`table_check_constraint_name` (Rust).
|
|
51
54
|
9. **Default values** — server-side defaults must serialize identically.
|
|
52
55
|
10. **Nullability** — must agree.
|
|
56
|
+
11. **Enum label additions** — the label-addition decision (which model-declared
|
|
57
|
+
labels a live enum type is missing, and which live labels are extra) and
|
|
58
|
+
the rendered `ALTER TYPE ... ADD VALUE IF NOT EXISTS` statement are decided
|
|
59
|
+
by ONE pair of functions: `ferro_ddl_lowering::missing_enum_labels` /
|
|
60
|
+
`extra_enum_labels` + `render_pg_enum_add_value`. The auto-migrate
|
|
61
|
+
reconciliation pass consumes them directly; the Alembic autogenerate
|
|
62
|
+
comparator consumes them over FFI (`_core._plan_enum_label_addition`) and
|
|
63
|
+
executes the byte-identical statements. Pinned by
|
|
64
|
+
`tests/test_cross_emitter_parity.py` and the ferro-ddl-lowering unit pins.
|
|
65
|
+
See ADR-0011 (append-only; update-gated; warn-never-act for extras).
|
|
66
|
+
12. **Check additions** — the missing-check decision (which declared `ck_*`
|
|
67
|
+
names — table checks, then column checks — a live table does not carry)
|
|
68
|
+
and the rendered ADD are decided by ONE pair of functions:
|
|
69
|
+
`ferro_ddl_lowering::missing_check_names` / `render_check_addition`.
|
|
70
|
+
The auto-migrate reconciliation pass consumes them through
|
|
71
|
+
`ferro_migrate::plan_missing_checks`; the Alembic autogenerate
|
|
72
|
+
comparator consumes them over FFI (`_core._plan_check_addition`) and
|
|
73
|
+
executes the byte-identical statements. Pinned by
|
|
74
|
+
`tests/test_table_check_reconcile.py`. See ADR-0013 (add on
|
|
75
|
+
`migrate_updates`; name-only comparison) and ADR-0014 (SQLite warn-skip).
|
|
76
|
+
13. **Check rebuilds** — the same-name body-drift decision (which declared
|
|
77
|
+
`ck_*` names exist live **and** whose catalog definition normalizes
|
|
78
|
+
unequal to the canonical rendering) and the rendered DROP + bare ADD
|
|
79
|
+
are decided by ONE pair of functions:
|
|
80
|
+
`ferro_ddl_lowering::drifted_check_names` / `render_check_rebuild`
|
|
81
|
+
(one normalizer: `normalize_check_definition`). The auto-migrate
|
|
82
|
+
reconciliation pass consumes them through
|
|
83
|
+
`ferro_migrate::plan_check_rebuilds`; the Alembic autogenerate
|
|
84
|
+
comparator consumes them over FFI (`_core._plan_check_rebuild`) and
|
|
85
|
+
executes the byte-identical statements. Pinned by
|
|
86
|
+
`tests/test_table_check_rebuild.py`. See ADR-0015 (canonical render vs
|
|
87
|
+
catalog, both through one normalizer) and ADR-0014 (SQLite warn-skip).
|
|
88
|
+
14. **Check leftovers / drops** — the leftover-name decision (which live
|
|
89
|
+
ferro-owned `ck_*` names a table carries that the model no longer
|
|
90
|
+
declares) and the rendered DROP are decided by ONE trio of functions:
|
|
91
|
+
`ferro_ddl_lowering::extra_check_names` /
|
|
92
|
+
`extra_check_names_warning` / `render_check_drop`. The auto-migrate
|
|
93
|
+
reconciliation pass consumes them through
|
|
94
|
+
`ferro_migrate::plan_check_drops` (ops only under
|
|
95
|
+
`migrate_destructive`; the warning always fires on `migrate_updates`).
|
|
96
|
+
The Alembic autogenerate comparator consumes them over FFI
|
|
97
|
+
(`_core._plan_check_drop`) with **no** destructive gate and executes
|
|
98
|
+
the byte-identical statements. Pinned by
|
|
99
|
+
`tests/test_table_check_orphans.py`. See ADR-0013 (leftover warning +
|
|
100
|
+
destructive ladder) and ADR-0014 (SQLite warn-skip).
|
|
53
101
|
|
|
54
102
|
### Why this invariant exists
|
|
55
103
|
|
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v0.19.0 (2026-08-18)
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
- Classify PG18 RESTRICT (23001) as ForeignKeyViolationError
|
|
9
|
+
([#338](https://github.com/syn54x/ferro-orm/pull/338),
|
|
10
|
+
[`4fa1153`](https://github.com/syn54x/ferro-orm/commit/4fa1153477802de8207c7987748db962b35c2f0f))
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- Named table-level CHECK constraints ([#356](https://github.com/syn54x/ferro-orm/pull/356),
|
|
15
|
+
[`ba179e7`](https://github.com/syn54x/ferro-orm/commit/ba179e71e9bce4ab77a6fdbc1831661485de6799))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## v0.18.0 (2026-08-05)
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
- **adr**: ADR-0011 label addition + glossary terms (enum label, label addition)
|
|
23
|
+
([`449616f`](https://github.com/syn54x/ferro-orm/commit/449616f07aefe473fe098f45f6873eb2003cf8e5))
|
|
24
|
+
|
|
25
|
+
- **migrate**: Label addition — the auto_migrate trap, the migrate_updates contract, the ordering
|
|
26
|
+
caveat ([#334](https://github.com/syn54x/ferro-orm/pull/334),
|
|
27
|
+
[`482911b`](https://github.com/syn54x/ferro-orm/commit/482911b441eeeed21b13d3927c9492797bb1eba5))
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
- **alembic**: Autogenerate comparator emits label additions from the shared diff
|
|
32
|
+
([#333](https://github.com/syn54x/ferro-orm/pull/333),
|
|
33
|
+
[`1579fc3`](https://github.com/syn54x/ferro-orm/commit/1579fc38a7f0d2b94c4ea51aa7daac652df30abc))
|
|
34
|
+
|
|
35
|
+
- **migrate**: Label addition tracer — migrate_updates appends missing enum labels
|
|
36
|
+
([#330](https://github.com/syn54x/ferro-orm/pull/330),
|
|
37
|
+
[`e929a6a`](https://github.com/syn54x/ferro-orm/commit/e929a6ae854fd435c6aac3277e476c15b106f73a))
|
|
38
|
+
|
|
39
|
+
- **migrate**: Warn-never-act for extra enum labels; create pass stays silent
|
|
40
|
+
([#331](https://github.com/syn54x/ferro-orm/pull/331),
|
|
41
|
+
[`a73d142`](https://github.com/syn54x/ferro-orm/commit/a73d142e2ff22ef8e47c2a8b8c34ca92372d0487))
|
|
42
|
+
|
|
43
|
+
### Testing
|
|
44
|
+
|
|
45
|
+
- **migrate**: Label addition edges — shared types, default-in-same-run, ordering, idempotence
|
|
46
|
+
([#332](https://github.com/syn54x/ferro-orm/pull/332),
|
|
47
|
+
[`1215f0c`](https://github.com/syn54x/ferro-orm/commit/1215f0c0e52367eafd91411b7b7891220edf318e))
|
|
48
|
+
|
|
49
|
+
|
|
4
50
|
## v0.17.1 (2026-07-19)
|
|
5
51
|
|
|
6
52
|
### Bug Fixes
|
|
@@ -129,13 +129,33 @@ The auto-migrate step that brings missing tables into existence — the table, i
|
|
|
129
129
|
_Avoid_: Bootstrap, ensure-tables, table sync
|
|
130
130
|
|
|
131
131
|
**Reconciliation pass**:
|
|
132
|
-
The `migrate_updates` step that alters existing tables to match the registered models
|
|
132
|
+
The `migrate_updates` step that alters existing schema objects — tables and ferro-owned enum types — to match the registered models; the only authority for DDL against an object that already exists. Within one table, column changes land before the indexes and constraints that reference them; label additions land before any table's changes.
|
|
133
133
|
_Avoid_: Update pass, schema sync, drift repair
|
|
134
134
|
|
|
135
135
|
**Ferro-owned artifact**:
|
|
136
|
-
|
|
136
|
+
A schema object ferro may reconcile to match the declared model. Indexes and constraints are ferro-owned by naming (`idx_`, `uq_`, `fk_`, `ck_`); native enum types are ferro-owned by derivation — the type's name matches the name ferro derives from the model. Artifacts owned neither way belong to the user and are never altered or dropped.
|
|
137
137
|
_Avoid_: Managed index, system constraint, internal index
|
|
138
138
|
|
|
139
|
+
**Enum label**:
|
|
140
|
+
One storable value of a native Postgres enum type, mirrored from a Python `StrEnum` member's value. Members are the Python-side declaration; labels are what the database accepts and stores.
|
|
141
|
+
_Avoid_: Enum value, variant, choice
|
|
142
|
+
|
|
143
|
+
**Label addition**:
|
|
144
|
+
The reconciliation-pass operation appending model-declared labels missing from a live ferro-owned enum type. Append-only and metadata-only: rows are never touched, and labels the database has but the model lacks are warned about loudly and never removed — removal and rename are reviewed-migration territory.
|
|
145
|
+
_Avoid_: Enum sync, label reconciliation, enum evolution
|
|
146
|
+
|
|
139
147
|
**Constraint rebuild**:
|
|
140
|
-
Drop-and-recreate of a ferro-owned constraint whose live definition no longer matches the declared model — a foreign key's `on_delete`, its target, its columns. Metadata-only: rows are never touched. On a backend that cannot alter constraints, ferro warns loudly and skips; it never diverges silently.
|
|
148
|
+
Drop-and-recreate of a ferro-owned constraint whose live definition no longer matches the declared model — a foreign key's `on_delete`, its target, its columns, or a table check's predicate. Metadata-only: rows are never touched. On a backend that cannot alter constraints, ferro warns loudly and skips; it never diverges silently.
|
|
141
149
|
_Avoid_: Constraint alter, FK patch, in-place constraint update
|
|
150
|
+
|
|
151
|
+
**Column check**:
|
|
152
|
+
A single-column CHECK that restricts a closed-domain field to its declared labels (`Field(db_check=True)` → `col IN (...)`). Named `ck_<table>_<col>`; not a table check.
|
|
153
|
+
_Avoid_: enum check, db_check constraint, value check
|
|
154
|
+
|
|
155
|
+
**Table check**:
|
|
156
|
+
A named boolean invariant over one row of one table, declared on the model as a lambda and enforced by the database as a CHECK constraint. The live name is `ck_<table>_<suffix>`; the suffix is what the model declares.
|
|
157
|
+
_Avoid_: table-level check, multi-column check, composite check, row check
|
|
158
|
+
|
|
159
|
+
**Check predicate**:
|
|
160
|
+
The lambda body of a table check — a ferro predicate over that model's own columns (or a forward-FK null test on the relation or its shadow `*_id`), with literal values only. Relation traversal, existence tests, and aggregates are not check predicates.
|
|
161
|
+
_Avoid_: check SQL, constraint expression, check body
|