
To migrate Oracle to PostgreSQL, you convert the schema, move the data, and rewrite the code that depends on how Oracle behaves. Tools such as ora2pg, AWS DMS Schema Conversion, Microsoft's VS Code extension and Google's Database Migration Service automate much of the schema work. The PL/SQL business logic and the SQL inside your applications are where the time goes.
Below: the main Oracle to PostgreSQL migration tools, described from their own documentation, the Oracle behaviors that break converted code, and whether PostgreSQL is better than Oracle.
- To migrate Oracle to PostgreSQL, convert the schema, move the data, then rewrite and test the code that depends on Oracle's behavior.
- ora2pg and the AWS, Microsoft and Google tools convert schema and much of the PL/SQL. Each one's documentation says manual work remains.
- Empty strings, DATE values, packages, CONNECT BY, autonomous transactions, ROWNUM and (+) joins are where converted code breaks.
- Whether PostgreSQL is better than Oracle depends on which Oracle features you use.
How to migrate Oracle to PostgreSQL
In five steps. The tools carry most of the first three.
- Assess. ora2pg's report mode and AWS's conversion assessment both show what won't convert automatically. ora2pg can estimate "the migration cost in person-days."
- Convert the schema. Tables, views, sequences and constraints. Watch the data types: Oracle's DATE holds a time.
- Move the data. AWS DMS and Google's Database Migration Service move data. ora2pg's site describes its data migration as "Offline, requires downtime."
- Convert the code. PL/SQL packages, procedures, functions and triggers, then the SQL in your applications, reports and jobs.
- Prove the behavior. Run the same inputs through both databases and compare outputs before cutover.
What are the best tools to migrate Oracle to PostgreSQL?
Usually the one built for where PostgreSQL will run. Here's what each tool's documentation says, checked 30 October 2026.
| Tool | What its docs say it converts | What's left to people |
|---|---|---|
| ora2pg: open source, any PostgreSQL | Schema, data, "functions, triggers, procedures, packages and package bodies," with "some basic automatic conversion of PLSQL code to PLPGSQL" | PL/SQL conversion "is a work in progress in Ora2Pg and you will likely have manual work" |
| AWS DMS Schema Conversion: Aurora or RDS for PostgreSQL | "Tables, views, stored procedures, functions, and other objects," with generative AI for objects its rules can't fully convert | A report of "what needs manual work." It "converts your database schema, not your data" |
| AWS Schema Conversion Tool: desktop | Schema, plus "SQL in your C++, C#, Java, or other application code" | Where schema can't convert automatically, AWS SCT "provides guidance" |
| PostgreSQL extension for VS Code: Azure Database for PostgreSQL | Schema and code objects, using models in Microsoft Foundry; application conversion is in preview | "A Converted status isn't a guarantee of compilation success, a complete implementation, or equivalent runtime behavior" |
| Google Database Migration Service: Cloud SQL for PostgreSQL | Tables, views, sequences, packages, functions, procedures and table-level triggers, with Gemini-assisted fixes, then the data | Deterministic conversion "supports a very specific subset of available Oracle database objects" |
On AWS, DMS Schema Conversion handles the schema and AWS DMS the data. On Azure, Microsoft's extension produces .sql files and says "generating these files doesn't deploy them."
Where does the time go in an Oracle to PostgreSQL migration?
In the code that carries business rules, and the SQL nobody counted. Converting a table is mechanical. Converting a PL/SQL package means deciding how it should behave, and only tests prove it. Microsoft says its own compile checks "don't test production data, application behavior, or every runtime path."
Packages are often where the rules live: eligibility, fees, status changes, rounding. Find out what they do before you translate them, with business rule extraction. Application SQL is the other half: queries in Java and C# code, in reports, and in Oracle Forms triggers. Microsoft warns that "AI-assisted code transformation can produce incorrect or incomplete results." An Oracle database full of PL/SQL is one of the classic legacy system examples.
Oracle to PostgreSQL differences that break code
Most of these convert without an error and still behave differently, which is why they need tests.
| Oracle | PostgreSQL | What breaks |
|---|---|---|
| Treats an empty string as NULL, and recommends you don't rely on it | Keeps them distinct; ora2pg's docs say "PostgreSQL differentiates between them" | IS NULL checks miss rows holding an empty string |
| DATE stores year to second | date is "date (no time of day)" | Mapping DATE to date drops the time, so cutoffs shift |
| Packages, with package-level variables | "Instead of packages, use schemas," with no package-level variables (porting guide) | State held in package variables must move, for example to temporary tables |
| Handlers roll back only to a SAVEPOINT you name | A caught exception rolls back "all database changes since the block's BEGIN" (porting guide) | Handlers that log an error and carry on lose earlier work |
| CONNECT BY hierarchies | WITH RECURSIVE | Hierarchy queries need rewriting, including loop handling |
| Autonomous transactions, "independent of the main transaction" | No such pragma; ora2pg emulates it with dblink or pg_background | Log rows written inside a failed transaction can roll back with it |
| (+) outer joins, which Oracle itself recommends replacing | LEFT JOIN and RIGHT JOIN | ora2pg tries "to rewrite simple forms of right outer joins"; the rest need a person |
| ROWNUM, numbered before an ORDER BY in the same query | LIMIT or row_number() | A LIMIT rewrite sorts first, so "first 10 rows" queries return different rows |
| SELECT ... FROM DUAL | "PostgreSQL allows one to omit the FROM clause" (SELECT reference) | Every FROM DUAL has to go |
Is PostgreSQL better than Oracle?
It depends on what you use. PostgreSQL is released under the PostgreSQL License, "a liberal Open Source license, similar to the BSD or MIT licenses," and its community supports each major version for five years, per its versioning policy. Tables and plain SQL move with little rewriting. A system built on packages and autonomous transactions takes real engineering time, and that time belongs in the comparison.
On Postgres vs Oracle performance, no general benchmark answers it for your workload. Convert a copy, load production-sized data, and run your heaviest queries and batch jobs on both. If support dates are driving the move, check them first: see Oracle 19c end of life and the risks of running end-of-life software.
Before you convert: what the 30-day assessment tells you
Conversion tools tell you what didn't convert. They can't tell you what your PL/SQL is for, which applications depend on it, or what breaks if it behaves slightly differently. The 30-day assessment covers that, fixed in scope, at a price agreed before we start. Over 30 days we read the codebase and the architecture around your Oracle databases: the packages, the applications and jobs that call them, and the SQL embedded in each. We map how the pieces fit together, find the hidden architectural debt, and flag security and compliance gaps.
The report says in plain language what is broken, what a move to PostgreSQL would take, and what to fix first. Your team can act on it, or we can do the migration as a separate project with its own scope and price. The report stands on its own. If an ora2pg report on one schema would answer your question, we'll say so.
Send one sentence about the Oracle system you want to move and what connects to it.