refactor: replace Any backend with typed engine#27
Merged
Conversation
Made-with: Cursor
Move runtime execution onto typed SQLite/Postgres pools and normalize schema metadata so runtime DDL, Alembic metadata, and backend-specific value handling stay in sync. Made-with: Cursor
Normalize non-JSON-native query payload values at the serialization boundary while preserving typed M2M IDs for direct Rust operations. Made-with: Cursor
Add relationship, query serialization, Postgres typed-cast, and static contract coverage so Python/Rust boundary regressions surface before user repros. Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
ac2fdec to
d8d376d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Ferro now executes through explicit typed SQLite and Postgres pools instead of the
sqlx::Anyruntime path. This removes backend ambiguity from the Rust core and makes schema metadata the shared contract for runtime DDL, Alembic metadata, query casting, hydration, and backend-matrix testing.This also fixes and hardens the class of bridge-boundary bugs exposed by UUID many-to-many relationships: query payloads now serialize non-JSON-native values safely, direct M2M operations keep typed IDs for Rust/Postgres binding, and new tests cover the places where the same logical value crosses Python JSON, PyO3, and backend-specific SQL boundaries.
Postgres coverage no longer depends on Supabase. The test harness can now run against an ephemeral local Postgres server via
pytest-postgresql, while still acceptingFERRO_POSTGRES_URLor the legacyFERRO_SUPABASE_URLfor externally managed databases.Changes
sqlx::Anyexecution with typedEngineHandle/EngineConnectionpaths for direct operations and transactions.json.dumps(query_def)in query methods.pytest-postgresqlto the dev and CI test dependency groups for local ephemeral Postgres coverage.FERRO_POSTGRES_URL, retainFERRO_SUPABASE_URLas a fallback, and supportFERRO_POSTGRES_PROVIDER=localto force the local provider.Bridge and Schema Impact
src/ferro/_core.pyiupdated (if needed)Migration / Breaking Changes
Documentation and Changelog
Test Plan
cargo test(15 passed)uv run pytest --db-backends=sqlite,postgres tests/test_auto_migrate.py::test_uuid_m2m_relationship_query_serializes_source_id -q(2 passed)uv run pytest --db-backends=postgres -q(221 passed, 5 skipped)uv run pytest --db-backends=sqlite,postgres -q(326 passed, 9 skipped)uv run pytest tests/test_db_backends.py -q(8 passed)FERRO_POSTGRES_PROVIDER=local uv run pytest tests/test_auto_migrate.py::test_uuid_m2m_relationship_query_serializes_source_id tests/test_structural_types.py::test_postgres_json_and_decimal_updates_keep_typed_hydration --db-backends=postgres -q(2 passed)Related Issues
Made with Cursor