Great question — and you’re right: out of the box, Prefect Server (Prefect 3.x) only supports PostgreSQL and SQLite as the orchestration database. Oracle isn’t supported today.
If you’d like to add Oracle as a supported backend, here’s the path to a viable PR, with the main components you’ll need to implement and the key places in the codebase to touch. I’ll also call out the biggest blockers to be aware of.
High-level plan
- Confirm an async path to Oracle in SQLAlchemy
- Prefect’s server uses SQLAlchemy’s AsyncEngine/AsyncSession. You’ll need either:
- A true async Oracle DBAPI supported by SQLAlchemy’s asyncio stack, or
- To use SQLAlchemy’s async fallback to run a sync DBAPI in a threadpool (if supported for Oracle).
- See:
-
SQLAlchemy asyncio docs
-
SQLAlchemy Oracle dialect
-
python-oracledb async guide
- Add an Oracle database configuration (engine/session)
- Implement an Oracle-specific configuration alongside Postgres/SQLite to create an async engine and sessions (or an async-fallback engine if a native async DBAPI is not available).
- Code location:
-
src/prefect/server/database/configurations.py
- You’ll wire up pool settings, connect args, and engine creation similar to existing backends.
- Implement Oracle query components (dialect-specific SQL)
- Prefect routes certain SQL constructs through “query components” to handle JSON, timestamps, inserts/merges, etc. You’ll need an Oracle implementation.
- Code location:
-
src/prefect/server/database/query_components.py
- Key areas to cover:
- JSON construction/aggregation (JSON_OBJECT / JSON_ARRAYAGG)
- Timestamp arithmetic and intervals
- Upsert/merge semantics (Oracle MERGE)
- Any JSON containment checks used by Prefect queries
- Add an Oracle ORM/migrations branch
- Prefect maintains dialect-specific Alembic migrations; you’ll add an “oracle” branch parallel to sqlite/postgresql and ensure types/indexes compile.
- Code locations:
- ORM config:
src/prefect/server/database/orm_models.py
- Migrations env + versions:
src/prefect/server/database/_migrations
- Things to adapt in migrations:
- UUIDs (e.g., use SYS_GUID() or store as RAW(16)/CHAR(36))
- Timestamps with time zone
- JSON columns (Oracle JSON or CLOB with JSON check)
- Enums → VARCHAR + CHECK
- Extension-dependent indexes (pg_trgm) → Oracle Text or alternatives
- Wire the dialect into dependency injection
- Teach Prefect how to instantiate your Oracle configuration, query components, and ORM config when it sees an Oracle connection URL.
- Code location:
-
src/prefect/server/database/dependencies.py
- Add Oracle-specific SQL compilation helpers (types/functions)
- Prefect has utility compilers for UUIDs, timestamps, JSON ops, etc. Provide Oracle compiles where needed.
- Code location:
-
src/prefect/server/utilities/database.py
- Update settings and docs
- Add allowed driver strings and connection URL guidance (e.g.,
oracle+oracledb://...
or appropriate async variant).
- Code location:
-
src/prefect/settings/models/server/database.py
- Tests and CI