Moving data out of a legacy database is one of the highest-stakes operations in any modernisation project. Get it right and the new system launches cleanly. Get it wrong and you spend months chasing data discrepancies, missing records, and broken relationships that undermine trust in the replacement system before it has had a chance to prove itself.
We treat database migration as an engineering problem, not a data entry task. Every migration we run follows a structured process: map the source, design the target, build the transformation logic, test exhaustively, and execute with a rollback plan.
The Reality
Legacy databases are rarely clean. They contain years of accumulated data — some structured well, some not, some duplicated, some orphaned, and some in formats that made sense at the time but do not map neatly to modern schemas. A database that started as a well-designed system ten years ago has almost certainly accumulated edge cases, workarounds, and data quality issues that nobody has addressed because the old system tolerated them.
The temptation is to migrate everything as-is and clean it up later. This is a mistake. “Later” never arrives, and the new system inherits all the problems of the old one. A proper migration is an opportunity to clean, restructure, and improve the data — but only if the migration is planned as an engineering project rather than a bulk copy operation.
The Risks of Doing Nothing
Leaving data in a legacy database means the business is permanently tethered to the legacy system. Even if a new application is built, it either needs to query the old database (creating a fragile dependency) or the data needs to be duplicated (creating a synchronisation problem). Neither option is sustainable long-term.
Legacy databases also carry security risks. Older database engines may lack modern encryption, access controls, and audit logging. Data stored in deprecated formats or on unsupported platforms is harder to protect and harder to recover if something goes wrong.
How We Approach This
We start by mapping the legacy database comprehensively — every table, every relationship, every data type, and every known inconsistency. We talk to the people who use the system to understand which data is critical, which is historical, and which can be archived or discarded.
We then design the target schema in PostgreSQL, making deliberate decisions about data types, relationships, indexing, and normalisation. The target schema is not a mirror of the source — it is designed for the new system’s requirements, with clean types, proper constraints, and a structure that supports the queries the business will actually run.
The transformation logic handles the conversion between source and target: reformatting dates, merging duplicate records, resolving broken foreign keys, and mapping old field values to new enumerated types. We build this as repeatable migration scripts that can be tested against a copy of the production data as many times as needed before the actual cutover.
We run the migration against test data first, validate the output with the business, fix any discrepancies, and repeat until the migration produces a clean, verified dataset. The final cutover is planned with a maintenance window and a rollback procedure so the business is never left without a working system.
What You End Up With
- Clean, structured data in a modern PostgreSQL database with proper types, relationships, and constraints
- Historical data preserved and accessible, either migrated into the new schema or archived in a queryable format
- Documented schema mapping showing exactly how the old data maps to the new structure
- Repeatable migration scripts that can be audited, re-run, and used as a reference for future data operations
- Confidence that the new system is built on reliable data from day one
What We Have Seen
We have migrated data from Access databases, legacy MySQL installations with inconsistent character encoding, flat-file systems, and even spreadsheets that had evolved into de facto databases over years of use. In one case, a business had customer records split across three different systems with no shared identifier — the migration involved building a matching algorithm that reconciled records by name, email, and address before merging them into a single clean dataset. The result was the first accurate customer count the business had seen in years.
Plan Your Migration
If you need to move data out of a legacy system, we can help you do it properly. Get in touch and we will start with a data audit.