How to migrate from Oracle to PostgreSQL without guessing at scope
The effort to move an Oracle database to PostgreSQL is set mostly by three things: how much procedural code exists, how much Oracle-specific SQL the applications depend on, and how tightly those applications are coupled to the database. The Ora2Pg assessment report is the first hard input for all three, so scope should not be estimated until the tool has run against a copy of the production schemas and the output has been reviewed. The migration itself covers schema conversion, PL/SQL conversion to PL/pgSQL, an offline data load, validation and cutover. Each stage can expand, and the inventory is what shows where.
Start with an inventory of code objects, not a count of schemas. Count packages, procedures, functions, triggers and user-defined types separately, because each carries a different conversion effort. For each object, record whether it calls Oracle-supplied packages such as DBMS_ or UTL_ utilities, uses autonomous transactions, relies on Oracle sequences or hierarchical queries, or uses Oracle-specific date and string functions. The assessment report should show which constructs it can convert and which it flags for manual work. Treat that classification as a starting point, and have your DBAs confirm the Oracle version and the features actually in use, because the report only sees the schemas it was given.
Database coupling extends outside the database. List every application service, batch job, reporting tool and integration that opens a connection, along with its driver and any embedded Oracle SQL. Look for behavior that PostgreSQL does not share, such as Oracle treating an empty string as NULL, implicit type conversions in comparisons, and identifier case handling. Each finding is a change request for an application team, and many will need a test cycle that the database team cannot close alone. Record a named owner for each one and decide early which changes belong in this migration and which wait for a later release.
Before the scope is fixed, settle three decisions in writing: the target PostgreSQL major version, the cutover window and the downtime the business will accept for the offline load, and who signs off that validation is complete. For the target version, use the supported releases listed in the PostgreSQL versioning policy and confirm their end-of-support dates on the day you decide, since the project sets those dates. A quote should follow from the completed inventory and the written scope. Ask any partner for the conversion list by object type, the assumptions behind each manual rewrite, the validation approach and an explicit list of exclusions.
Which Oracle features map cleanly to PostgreSQL and which need redesign
This table compares common Oracle features with their PostgreSQL equivalents and marks each as usually direct, needing a type or syntax conversion, or needing redesign. Use it to see where migration effort will concentrate in your schema and code. The assessment report and a pilot confirm each row for your estate, because object counts and actual usage decide how much each feature matters.
| Oracle feature | PostgreSQL equivalent | Usual mapping |
|---|---|---|
| Tables, constraints, sequences and identity columns | Tables with primary, foreign and unique keys, CHECK constraints, identity columns and sequences | Usually direct. Check deferred constraints and sequence caching in the pilot |
| NUMBER and DATE types | numeric, integer and timestamp types | Type conversion. Oracle DATE carries a time part, so map it to timestamp where needed |
| CLOB and BLOB | text for character data and bytea for binary data | Type conversion. Review value sizes and the load method for large objects |
| PL/SQL packages, procedures and functions | PL/pgSQL functions and procedures, with packages mapped to schemas and functions | Usually needs redesign. Package state and autonomous transactions have no direct equivalent |
| Triggers | PL/pgSQL trigger functions attached to tables | Type or syntax conversion. Rewrite trigger bodies and confirm firing order and compound trigger logic |
| Synonyms and database links | Views or search_path for synonyms, and postgres_fdw or application-level access for remote data | Synonyms usually direct. Database links usually need redesign of remote access and credentials |
| Materialized views | Materialized views refreshed with REFRESH MATERIALIZED VIEW and scheduled jobs | Usually needs redesign. Oracle fast refresh and refresh scheduling need planned replacements |
| Partitioning | Declarative partitioning by range, list or hash, with partitioned indexes | Usually needs redesign. Partition keys, local indexes and maintenance jobs need review |
| Oracle-specific SQL functions and hierarchical queries | COALESCE, CASE, window functions and WITH RECURSIVE, among others | Syntax conversion for many functions. CONNECT BY and ROWNUM logic often needs redesign |
PL/SQL to PL/pgSQL: what to expect when you migrate from Oracle
Stored code is where most of the manual effort in an Oracle to PostgreSQL migration will sit. PL/SQL packages, stored procedures and triggers look similar to PL/pgSQL on the page, which tempts teams to assume that a converted file will behave the same way. It often will not. Plan for the differences in exception handling, package state, cursor behavior, autonomous transactions and built-in packages before you estimate the code workstream, and treat every package as a unit of rework rather than a line-by-line translation.
Ora2Pg converts the parts of PL/SQL it can map to PL/pgSQL and writes the results into files you can review. Its coverage changes between releases, so confirm for the exact Ora2Pg version you plan to use which object types, statements and built-in functions it converts automatically, which it converts partially, and which it flags for manual work. Run it against a copy of your schema first and record the counts of converted and flagged objects. Those counts, not the total object count, are the starting point for the effort conversation with any partner or internal team.
Review converted code with the Oracle source open beside it. Check package initialization blocks and any session-level variables, because PostgreSQL has no direct equivalent of package state that persists across calls in the same session. Check every exception handler, since error codes, named exceptions and the behavior of unhandled errors differ. Look at cursor loops and any use of implicit cursor attributes. Where code relies on autonomous transactions, decide whether to move the work into a separate procedure that uses dblink or a queued write, or to redesign the logic. Record each decision, because auditors and application owners will ask why a given construct changed.
Keep a regression test suite that runs the same business cases against Oracle and PostgreSQL. Choose cases from the processes that matter most to the business, such as end-of-day batch jobs, interest or fee calculations, and reporting queries, and capture the expected outputs from the Oracle system. Run identical inputs through both databases and compare results, including rounding, null handling, date arithmetic and ordering of rows without an explicit sort. Automated comparison catches defects that code review misses, and it gives you evidence to show during cutover sign-off.
Ask any partner to show how they will track converted, flagged and rewritten objects, who owns each decision, and how the test suite will be maintained after cutover. Confirm whether the test cases and comparison scripts become your property, and whether the database team will be able to run them without the partner. These questions matter more than the conversion percentage, because the code you inherit will change as the application changes.
Documented tools for an Oracle to PostgreSQL migration
Ora2Pg and PostgreSQL's own loading tools cover the documented path from an Oracle schema and its data to a PostgreSQL target. The cards below describe what each tool produces, what it leaves for hand work, and what your team must check in the output before cutover. This page covers only this path. Other migration routes are outside its scope.
Ora2Pg assessment report
Ora2Pg's assessment report inventories the Oracle objects in scope, including tables, views, packages, triggers, sequences and database links, and reports an estimate of conversion effort. Use it to size the work before setting a schedule. Check its object counts against your own data dictionary queries, and treat the effort estimate as a starting point that your team validates against the actual PL/SQL.
Ora2Pg schema export
Schema export generates PostgreSQL DDL for tables, constraints, indexes, sequences and views from the Oracle data dictionary. The output is a starting script, not a finished target schema. Review primary keys, foreign keys, check constraints and index definitions against the source. Confirm that objects Ora2Pg cannot translate appear in a list for manual work and are not silently dropped.
Ora2Pg type mapping
Type mapping decides how Oracle NUMBER, VARCHAR2, DATE, TIMESTAMP, CLOB and BLOB columns become PostgreSQL types. The default mapping should be confirmed column by column, especially for NUMBER precision, DATE columns that carry time components, and character set and collation settings. Record each override in version control so the mapping can be reviewed and repeated on every test run.
Ora2Pg data export
Data export extracts table contents from Oracle into files that PostgreSQL can load. Plan the offline window around the largest tables, and confirm how LOB columns, binary data, empty strings and NULL values are represented in the output. After loading, compare row counts and checksums for each table against the source taken at the same point in time, and record any differences for investigation.
Ora2Pg PL/SQL conversion
Ora2Pg converts many PL/SQL constructs to PL/pgSQL, but packages, autonomous transactions, dynamic SQL and Oracle-specific built-in packages usually need hand rewriting. Review each converted function and procedure against its original behavior, including exception handling and commit behavior. Test every routine with representative inputs, because a conversion that loads without error can still return different results.
COPY and psql for bulk loading
PostgreSQL's COPY command loads the exported data files into target tables, and psql runs the generated DDL and post-load scripts in a controlled order. Create schema objects in dependency order, and load data before building foreign keys and secondary indexes where practical. Capture psql error output in the run log, and confirm that sequences are reset above the loaded maximum values before the application reconnects.
The sequence for an Oracle to PostgreSQL cutover with a parallel run
This sequence moves an Oracle estate to PostgreSQL in controlled stages, with each stage producing evidence that the next one depends on. It ends with a cutover decision backed by reconciliation results and a documented retention period for the Oracle environment.
Inventory the Oracle estate and run assessment
Your DBAs and application owners list every schema, package, job, database link and application that touches the Oracle databases. DeployOpen then runs the Ora2Pg assessment report against the agreed schemas and reviews the output with your team to flag objects that need manual work. The step is complete when the inventory is signed off by your DBA lead and each application owner confirms their dependencies are listed. The output is the assessment report, the object inventory and an agreed list of open questions for the Oracle-specific features that Ora2Pg cannot convert automatically.
Select the target PostgreSQL major version
Using the assessment and your application compatibility needs, the team chooses the target PostgreSQL major version and records the reasoning. The versioning policy sets the support window for each release, so the choice should account for when the version reaches end of support. PostgreSQL 14 reaches end of support on November 12, 2026, while PostgreSQL 18 is supported until November 14, 2030. The output is a short decision record covering the version, its support end date, and the planned upgrade path. Your platform owner and security lead sign off, because the version also sets the authentication and extension options available to you.
Pilot the conversion on a representative schema
The team selects one schema that covers the common data types, constraints, indexes and at least some of the Oracle-specific objects in your estate. Ora2Pg converts it into the target version, and DeployOpen reviews the generated DDL and data type mappings against your data dictionary. Anything that fails or converts incorrectly is logged with a proposed fix. The step is complete when the pilot schema loads into a test database, the object counts match the source, and the failure list has an owner for each item. Your database architect and the lead application developer sign off on the mappings before the wider conversion starts.
Convert and review PL/SQL code
Packages, procedures, functions and triggers are converted to PL/pgSQL, with the automatic output checked line by line where the logic is business-critical. Each converted routine that does not compile or behaves differently in tests goes onto a manual rewrite list with an assigned developer. The team runs a regression suite of known inputs against the Oracle and PostgreSQL versions and compares the results. The step is done when every routine is either converted and tested or listed with an approved manual change. Your senior developer and DBA sign off on the code, and the business owner of any financial or regulatory calculation signs off on its results.
Rehearse the offline data load
The team runs the full offline data load into a non-production PostgreSQL environment at least once, using the same scripts and steps planned for cutover. Each rehearsal records the elapsed time, the errors encountered and the checks performed after loading, including row counts and checksums for the largest tables. Ask your DBAs to measure the load time against the window your business can accept, because the figure comes from your data volume and hardware rather than from any generic estimate. The step is complete when two consecutive rehearsals produce matching results and the runbook reflects every correction. The operations owner signs off on the runbook.
Run the parallel run with reconciliation
Both databases receive the same business activity for an agreed period while the applications continue to read from Oracle. Your team keeps PostgreSQL current with a change capture method that you select and confirm for your environment, and the reconciliation job compares key tables, aggregates and sample business transactions between the two systems. Each mismatch is logged, investigated and either fixed or accepted with a documented reason. The step is complete when reconciliation reports show no unexplained differences in the agreed scope. The business owner and your data owner sign off on the results, because they decide whether the differences are acceptable.
Cut over applications to PostgreSQL
The team holds a go or no-go review against a written checklist that covers the reconciliation results, the rollback plan, the final load and the monitoring in place. At the agreed point, Oracle writes stop, the final delta is applied, applications are repointed to PostgreSQL, and the post-cutover validation checks run. The rollback plan states who makes the call to revert, how long the revert takes to execute, and what data is re-synchronized. The step is complete when the applications run on PostgreSQL and the validation checks pass. The change advisory board and the service owner sign off, and the Oracle database stays available for rollback until the retention period begins.
Decommission Oracle after the retention period
After the agreed retention period ends, the team takes a final verified backup of the Oracle databases and moves it to the archive your records policy requires. Access to the source environment is removed in stages, and the Oracle licence and support contracts are terminated or reduced in line with what you no longer use. The retention period itself is set by your legal, compliance and data owners, so confirm its length with them before the cutover. The step is complete when the archive restore has been tested, access has been revoked, and the decommissioning record is filed. The data owner and compliance lead sign off on the closure.
Planning the offline data load and validating data before cutover
An offline initial load copies the Oracle data into PostgreSQL while the source is frozen, so both sides hold the same consistent snapshot. Without a freeze, rows written during the copy can land in one table but not its parent, and reconciliation later becomes guesswork. The decision to make early is how long the application can be unavailable, because that window sets the ceiling on how much data you can move in one pass. Confirm the business tolerance for read-only time with the application owners before anyone plans the load itself, and record it in the cutover runbook. Plan the window from rehearsal timings, not estimates. Run the full Ora2Pg data export and import at least twice against a copy of production sized like production. Time each table, index build and constraint validation separately, and note where the time goes. Index creation and foreign key validation often dominate, which is why many teams load data first and build indexes and constraints afterward. Use the rehearsal figures, plus a margin you agree in advance, to set the window. If the rehearsal overruns, reduce the work inside the window (parallel table jobs, deferred indexes, or moving history tables to a separate phase) rather than extending the window on hope.
Order the loads around dependencies. Load parent tables before child tables so foreign keys can be validated as they are added, or add them as NOT VALID and validate them after the data is in. Load reference and lookup tables first because many other tables depend on them. Reset sequences only after the data load finishes, setting each one above the maximum migrated key so new inserts do not collide. Handle large LOB columns (BLOB and CLOB data) as a separate track: they are slow to move, can dominate memory and I/O, and sometimes benefit from being exported in chunks or migrated after the main window if the application can tolerate the delay. Decide per table, and test each LOB path in the rehearsal.
Validate in layers. Start with row counts per table, compared between Oracle and PostgreSQL after the freeze. Counts catch missing tables and failed batches but not corrupted values, so add checksums or sampled value comparisons for critical tables. Hash a normalized column list on both sides, or compare a fixed random sample of primary keys field by field, and document how dates, timestamps, numeric precision and character encodings are normalized. Then check sequence positions against the maximum keys in use, and confirm that every constraint, index and trigger you planned exists and is valid. Ora2Pg's reports help, but verify the results yourself.
Reconcile business totals before cutover. Choose a small set of figures the business already trusts, such as account balances, open order value, invoice totals by period or record counts per customer segment. Run the same queries on Oracle and PostgreSQL against the frozen snapshot and require exact matches or a documented explanation for each difference. Involve finance or operations owners in signing off these results, because they catch logic errors that technical checks miss. Keep the queries, outputs and sign-off in version control as cutover evidence. Decide what blocks cutover. Agree before the rehearsal which mismatches stop the go-live decision, such as any count difference on a financial table or any failed constraint validation, and which are acceptable with a written reason. Confirm with your own data governance and compliance owners how validation records are retained, because they may be needed later for audit.
Effort drivers when you migrate from Oracle to PostgreSQL
This table lists the factors that raise or lower the cost and duration of an Oracle to PostgreSQL migration, whether each one is paid once or recurs, and what to request in a written quote. Use it to compare your own database estate against the drivers before asking for a scope. Most of the cost sits in PL/SQL volume, Oracle-specific features and downtime constraints, so those rows deserve the most detail in a quote.
| Driver | Why it changes effort | One-time or recurring | What to ask for in a quote |
|---|---|---|---|
| PL/SQL volume and count | Each package, procedure, trigger and function must be converted to PL/pgSQL and retested, so line count and object count drive most build effort. | One-time | Object inventory by type, lines of code per package, and the conversion approach for each object class. |
| Oracle-specific features | Packages, autonomous transactions, DBMS_* calls, sequences used in unusual ways and Oracle-only SQL syntax need manual rewrites or replacement logic. | One-time | A list of features found in the Ora2Pg assessment report and which items are estimated as manual work. |
| LOB and large object data | BLOB and CLOB columns affect load method, transfer volume, storage planning and how long the offline load takes. | One-time | Total LOB size, column count, load method and the expected transfer window in your network. |
| Partitioned tables | Oracle partitioning schemes must be mapped to PostgreSQL declarative partitioning, and partition keys and local indexes must be checked. | One-time | Count of partitioned tables, partition types, and how each maps to the target design. |
| Applications and reports querying directly | Every application, ETL job and reporting tool that issues Oracle SQL or uses Oracle drivers needs query changes and regression tests. | One-time, with ongoing query maintenance if apps keep changing | List of connected systems, driver types, and the test coverage each one has today. |
| Data quality | Invalid dates, orphaned rows, character set issues and constraint violations surface during load and must be cleaned or agreed. | One-time | Who owns data cleanup decisions, the rules for rejected rows, and the reconciliation reports to be produced. |
| Downtime window for cutover | A short approved outage pushes the team toward a tested offline load or a replication-based approach, which changes tooling and rehearsal count. | One-time | The approved outage window, number of rehearsal cutovers included, and the rollback plan. |
| Number of environments | Each environment needs its own load, configuration and test cycle, so development, test, staging and production multiply the work. | One-time for setup, recurring for keeping environments in sync | Environments in scope, refresh frequency, and whether data masking is needed in non-production. |
| Compliance evidence requirements | Auditors may expect migration test records, access control changes and data reconciliation evidence, which must be collected during the project. | One-time to produce, with retention of records | Evidence list, format, retention period, and which controls must be documented for your assessor. |
| Team skills on both platforms | Gaps in Oracle knowledge or PostgreSQL operations lengthen analysis, code conversion and post-cutover tuning. | One-time, plus recurring operator training | Which roles the vendor covers, which roles you staff, and any knowledge transfer sessions included. |
| Post-cutover operations | Backups, replication, failover tooling and connection pooling must be set up for PostgreSQL, and they need ongoing maintenance. | Recurring | Whether backup testing, point-in-time recovery tests and PostgreSQL minor update support are in scope or handled by your team. |
What usually goes wrong in an Oracle to PostgreSQL migration
Most failed Oracle to PostgreSQL migrations break in the same few places, and the problems usually surface after the schema has already loaded. Each risk below has a prevention step your team can run and check in its own environment before cutover.
Underestimating PL/SQL conversion
Ora2Pg's assessment report counts and classifies database objects, but it does not guarantee that packages, triggers and procedures will run unchanged in PL/pgSQL. Teams that size the work from object counts alone often find that autonomous transactions, package state and Oracle-specific built-ins need manual redesign. Before committing to a schedule, have the team hand-convert a representative sample of packages and check each converted routine against its Oracle output with the same inputs.
Unchecked data type changes
Oracle NUMBER without a declared precision, DATE values that carry a time component, and TIMESTAMP WITH LOCAL TIME ZONE can all map to PostgreSQL types that store different values. Ora2Pg applies a default mapping, and that default may not match your data. Review each mapped column against its actual value range, then compare row counts, sums and sampled timestamps between source and target after the load.
Sequences left behind after load
Bulk loading rows with explicit key values does not advance PostgreSQL sequences, so the first insert after cutover can collide with existing keys. Identity columns and serial-style defaults need the same attention. As a post-load step, set each sequence to the maximum value of its column, then confirm that the next generated value is higher than any existing key in every table.
Application SQL that assumes Oracle
Application code often depends on Oracle behavior such as implicit type conversion, ROWNUM pagination, empty strings treated as NULL, and case handling in identifiers. PostgreSQL treats these differently, and some queries will return wrong results without raising an error. Inventory the SQL your applications send, run the test suite against PostgreSQL, and compare result sets for critical queries against the Oracle baseline.
Connection and authentication gaps
Applications that connect to Oracle with older drivers or password hashes may need new drivers, changed connection strings and updated pg_hba.conf rules before they can reach PostgreSQL. PostgreSQL has deprecated MD5 password authentication in favor of SCRAM since version 18, so check which method each client supports. Confirm driver versions, the authentication method per client, and connection pool sizing in a staging environment that mirrors production.
Cutover without a tested rollback
A cutover plan that only describes the forward path leaves no defined way back if the new database misbehaves in the first hours. Decide how you will return traffic to Oracle, including how writes made on PostgreSQL would be carried back, and rehearse that path with the same timing and data volume as the real cutover. Record the rehearsal results and the go and no-go criteria before the production window is booked.
What changes for your applications after the database moves
Plan application work as its own workstream before the data moves. Start with connections. Each application uses an Oracle client library, such as a JDBC, ODP.NET or OCI driver, and a connection string that names an Oracle service, a host and a schema. Those drivers must be replaced with PostgreSQL drivers, and connection strings, TLS settings and the default schema or search_path must be rewritten and tested. Ask each team to list its driver, its driver version, its ORM and the database account it connects as. Oracle schemas map to PostgreSQL schemas and roles, so the list also shows which application accounts need grants in the target. Treat the inventory as the input to every later test, because a missed connection usually surfaces only after cutover.
Generated SQL is the second area. Ora2Pg's assessment and conversion output covers the database objects it can read, such as PL/SQL packages and procedures, but queries built by ORMs, query builders and reporting tools are assembled at runtime and need their own review. Look for Oracle-specific constructs such as ROWNUM, the (+) outer join operator, DECODE and NVL, DUAL, and sequence references written in Oracle form. Also check how each ORM is configured for its dialect, how empty strings are handled, since PostgreSQL keeps empty strings distinct from NULL, and how date and timestamp arithmetic behaves. Capture statements from application logs or a trace during a representative test run, then replay them against PostgreSQL. A query that parses but returns different rows is the failure to look for.
Transaction and isolation assumptions need the same scrutiny. Both databases default to READ COMMITTED, so simple reads behave similarly, but the details differ. Review code that relies on readers never blocking writers, on particular locking behavior from SELECT ... FOR UPDATE, or on how sequence values are used after a rollback. PostgreSQL can return serialization failures at REPEATABLE READ and SERIALIZABLE, so any code that uses those levels needs retry logic. DDL is transactional in PostgreSQL, which changes how deployment scripts handle partial failures. Check the autocommit setting in each driver, because a driver default can change how a batch job commits. Write these checks into the test plan with a named owner for each one.
Authentication and pooling decide how applications connect in production. PostgreSQL 18 deprecates MD5 password authentication in favor of SCRAM, so new roles should use SCRAM and existing MD5 roles should be migrated before the cutover window. The client authentication documentation lists several methods, including password, GSSAPI, SSPI, LDAP, RADIUS, certificate, PAM and OAuth. Confirm which method each application and reporting tool can use with its driver, and confirm the choice against your own identity setup, including the directory, the Kerberos realm, the certificate authority and the service accounts. If connection pooling with PgBouncer is part of the design, choose the pooling mode with care, because session-level state and prepared statements behave differently across modes. Confirm that you run a current PgBouncer release, since version 1.26.1, released October 14, 2026, included security fixes.
Reporting tools need their own plan. Most BI and dashboard products connect to Oracle through a vendor driver, a semantic layer or saved queries that reference Oracle schema names. Build an inventory of every report, dashboard, extract and scheduled export, with its owner and the connector it uses. Identifier case is a common trap. Oracle folds unquoted identifiers to uppercase, while PostgreSQL folds them to lowercase, so queries and metadata that quote names can fail or return nothing. Ask each tool vendor which PostgreSQL driver and authentication methods it supports for your version. Then run each high-value report against a restored copy, compare the results with the Oracle output, and agree the cutover order with the business owners of those reports.
Questions teams ask before they migrate from Oracle to PostgreSQL
How is the cost of an Oracle to PostgreSQL migration set?
The cost follows from the scope of the work, which the assessment reveals, so there is no fixed price for every database. One-time costs usually cover the assessment, schema and PL/SQL conversion, application changes, data load rehearsals, validation and cutover support. Recurring costs begin after go-live and include hosting, backups, monitoring, patching and any support retainer. Costs rise with the number of stored packages, the Oracle-specific features in use, data volume and the number of applications that query the database. Ask for a quote that lists each deliverable, the client responsibilities, the exclusions and the recurring costs for running the platform afterward. DeployOpen does not publish prices. A quote follows from the written scope.
How long does an Oracle to PostgreSQL migration take?
No duration is stated before the assessment because the timeline depends on facts the team does not yet have: database size, the number and complexity of stored code objects, how many applications connect, and how much downtime the business accepts at cutover. The assessment report from Ora2Pg is the first input that makes those facts measurable. After it, a fixed-scope proposal can set phases, dependencies and a schedule. Schedule risk usually sits in code conversion and validation more than in the data copy itself, so ask for a plan that reserves testing time explicitly. Illustrative: a schema with heavy package logic often takes longer to validate than a simpler schema of similar size. Ask that each phase be tied to a written acceptance check.
What must our team provide before an outside migration starts?
Plan to provide four things: schema access through a read-only account that can see every relevant owner and object, a current application inventory listing each system that connects along with its drivers, queries and batch jobs, representative test data, and named business owners who sign off on data rules, reconciliation results and the cutover window. Masked copies may be needed where production data is regulated, so confirm with your security team how copies are approved and stored before any data leaves production. Also provide a test environment sized close enough to production to measure load times, and a change calendar. A missing application inventory is a frequent cause of late validation problems, because hidden consumers surface only after testing begins.
Can our internal team migrate Oracle to PostgreSQL alone?
Yes, a team with strong Oracle and PostgreSQL skills can run the migration in-house. Outside help usually adds value in three places: an early assessment that sets scope before commitments are made, experienced conversion of PL/SQL that does not map directly to PL/pgSQL, and independent validation of data and application behavior before cutover. Internal teams often struggle when the same people must keep production Oracle running, build the PostgreSQL platform and handle application changes at the same time. Count the people who know PL/SQL, who own each application and who can hold a cutover window. The decision depends on that capacity and on your organization's tolerance for risk during cutover.
Which PostgreSQL version should we target for an Oracle migration?
Target the newest supported major version that your application vendors and extensions support. Based on the published dates, PostgreSQL 18 is the current choice. It was first released September 25, 2025, and is supported until its final release on November 14, 2030. PostgreSQL 17 is supported until November 8, 2029, and PostgreSQL 16 until November 9, 2028. PostgreSQL 14 reaches end of support on November 12, 2026, so a new deployment on it would need another upgrade within a short period. Confirm with each application vendor and extension owner which versions they certify, because the newest release helps only if your stack runs on it. Review the PostgreSQL versioning policy before fixing the target.
How do we ask for a fixed-scope quote for an Oracle migration?
Ask for a written scope that lists deliverables, phases, acceptance criteria, client responsibilities, assumptions, exclusions and schedule dependencies. If the scope is not yet clear, start with a scoped assessment so the quote rests on measured facts. A useful request includes database versions and sizes, the number of schemas and applications, the target PostgreSQL version, the downtime the business accepts at cutover and the support expected after go-live. Ask the provider to separate one-time work from any retainer, and to state what is excluded, such as application code changes that your own developers own. DeployOpen plans most engagements as fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
What breaks most often when PL/SQL moves to PL/pgSQL?
Procedural code is where most rework concentrates, because PL/SQL packages, autonomous transactions, bulk collect patterns and Oracle-specific functions do not map one-to-one to PL/pgSQL. Expect manual rewrites for packages, exception handling and cursor behavior that differs between the two engines. Ora2Pg reports what it can convert and flags constructs it cannot, which gives you a list to size the rework. Also check date and number formatting, NULL handling for empty strings, identifier case sensitivity and transaction isolation assumptions in applications. Compare results row by row for critical reports, using production-like data and workloads. Treat converter output as a draft that requires review and testing.
How DeployOpen scopes, delivers and supports an Oracle to PostgreSQL migration
DeployOpen plans and runs Oracle to PostgreSQL migrations with Ora2Pg inside infrastructure you control. Engagements are fixed-scope, so the scope, deliverables and timelines are agreed in writing before work starts, and ongoing support is available as a retainer after cutover.
How we scope
- Written scope names the Oracle databases, schemas, PL/SQL objects and applications included in the migration
- Ora2Pg migration assessment report reviewed to size manual PL/SQL conversion and unsupported Oracle features
- Target PostgreSQL major version, cutover window and rollback criteria agreed before any build work begins
How we build
- Ora2Pg configured to export schema, data and objects, with conversion output reviewed object by object
- PL/SQL packages, procedures and triggers converted to PL/pgSQL and tested against expected results
- Offline data load planned with load order, sequences, constraints and indexes rebuilt for performance
How we hand over
- Validation scripts compare row counts, checksums and sample query results between Oracle and PostgreSQL
- Runbooks document cutover steps, rollback path, connection string changes and post-migration checks
- Converted code, conversion decisions and open items documented so your team can maintain PostgreSQL
How we support
- Post-cutover monitoring and fixes for converted objects during the support period agreed in the written scope
- Ongoing support, upgrades and testing available as a retainer after the database goes live
- Optional follow-on work: high availability, tested point-in-time recovery and connection pooling for PostgreSQL

