Dev.to WebDev 🛠 Dev 👁 0 📖 7 min read

Migrating a Microsoft Access Database to a Web App: What Moving an Agency’s CRM Taught Me

The import isn't the hard part. Keeping your records connected is. I rebuilt a CRM for an agency three times. Not because the code kept falling over, but because I kept finding out what the job actually was. The agency

The import isn't the hard part. Keeping your records connected is.

I rebuilt a CRM for an agency three times. Not because the code kept falling over, but because I kept finding out what the job actually was.

The agency hired me as an independent freelancer. Their contacts and deals lived in a Microsoft Access database, and all of it had to come across into a new CRM. On paper, that sounds like exporting a few tables and importing them somewhere else. It wasn't. The hardest part had nothing to do with screens or features. It was making sure every deal was still attached to the right person after the move.

If your business runs on an Access database and you're thinking about moving it to a web app, here's what I'd want you to know before you start. Or before you hire someone to do it for you.

Why businesses end up here

A lot of Access databases start the same way. Someone builds a few tables and forms, it works, and the business slowly grows around it. Years later it holds the contacts, the deals, the history, and a fair amount of knowledge that nobody ever wrote down anywhere else.

For this agency, the reason was simple. They wanted their database hosted in the cloud instead of sitting in an Access file.

None of that means Access was a mistake. It got the business this far. The trouble starts when you try to leave.

The part everyone underestimates: relationships

Here's the thing that's easy to miss until you hit it.

In an Access database, every contact has an ID. Every deal points at a contact by that ID. Say a deal belongs to contact 1042. That number is how the database knows whose deal it is.

When you move into a new system, the new system usually generates its own IDs. Contact 1042 in Access might become contact 87 in the new CRM. That's normal. But if you import the contacts, then import the deals on their own, the deals still say "1042". In the new system, 1042 is either somebody else entirely or nobody at all.

The scary part is that nothing looks broken. You end up with valid-looking contacts and valid-looking deals, and the connections between them are gone. Or worse, quietly wrong.

So the critical piece of the whole migration wasn't the importer. It was a mapping: for every record in Access, which new ID did it become? Once that mapping exists, every deal can be translated to point at the right contact in the new system.

It's boring bookkeeping. It's also the whole job.

Your data is messier than you think

That mapping would be easy if every contact were cleanly identifiable. They weren't.

The agency's data had duplicate names. Some contacts had no email address. Phone numbers were written in different ways. Dates weren't consistent either. No single field could be trusted, on its own, to tell me that two records were the same person.

So I used two rules to find possible matches:

  • name plus email
  • name plus phone, when there was no email

The important word there is possible. Neither combination is guaranteed to be unique across a whole dataset. Two people can share a name. A phone number can belong to an office rather than a person. So a match under those rules is a candidate, not proof.

That distinction matters more than it sounds. If you treat a candidate as a confirmed match and merge automatically, you risk attaching a deal to the wrong contact. And a wrong link is much harder to notice later than a duplicate you can see.

Let the person who knows the data decide

Where the rules couldn't settle it, the import had a review step. It showed the affected records to the person responsible for the data, so they could look at them before the import was confirmed.

I like this approach because it's honest about what code can and can't know. The rules can narrow things down. They can't know that "J. Smith" with no email is the same John Smith your team spoke to last spring. The person who works with those contacts every day often can.

There's a cost. A review step takes someone's time, and it slows the migration down. But I'd rather spend an afternoon of a person's attention than leave a decision like that to a guess.

If you're planning a migration, budget for this. Someone on your side will need to look at the records the rules can't settle. That's not a sign the project is going badly. It's the project working as it should.

Build the new system for the people who'll use it

The migration was the bigger problem, but it wasn't the only lesson.

My first version of the CRM was designed around my own assumptions as a developer. I was thinking about what the system needed, not what the people using it were trying to get done. And the people using it weren't technical.

Form validation wasn't strong enough, so input got through that should have been caught. Some interactions confused people. I've come to think of it this way: when a screen needs explaining, the screen is the bug.

Validation matters twice as much after a migration. You've just spent real effort getting clean, connected data into the new system. Weak forms let the mess straight back in.

Three builds, one change in thinking

Looking back across the three builds, the biggest change wasn't in the code. It was in where I started.

At first, I started with what to build. By the end, I started with three questions. Who will use this? What does the existing data really contain? And what would be unacceptable to get wrong? For this agency, the answer to that last one was clear: a deal attached to the wrong contact.

I don't have metrics to share from this project, and I'm not going to make any up. I also wouldn't call the result perfect, and I'm sure the old data held problems I never saw. But the way I approach this kind of work changed for good, and those three questions are where I'd start any migration now.

If you're planning your own Access migration

Whether you do it yourself or hire someone, here's what I'd check before any code gets written:

  1. Look at the real data early. Not a description of it. An actual copy. Duplicates, blanks and odd formats show up fast once you look.
  2. Decide how record identity will work before building the importer. How will each old record be linked to its new ID? If nobody can answer that, the migration isn't ready to start.
  3. Ask how related records stay connected. If the plan is "export the tables and import them", ask what happens to the links between contacts, deals, invoices or whatever your data holds.
  4. Ask what happens to records the rules can't match. There should be a clear answer, and it shouldn't be "we merge them automatically and hope".
  5. Plan time for someone on your side to review. The person who knows the data is part of the migration, not just the person who signs it off.
  6. Test the new system with the people who'll use it every day. If they need you to explain a screen, fix the screen.

None of this is complicated. It's just easy to skip when you're focused on the new system and the old one feels like something to get rid of.

Where to see more

I'm Ayman Atif, a freelance software developer. I build business software for startups, small businesses and agencies, and a good share of that work starts with an old spreadsheet or database that nobody wants to touch.

I wrote up the matching workflow and the trade-offs in more detail as a case study on my site: CRM rebuild and Microsoft Access migration. You can see the rest of my work at ayman-atif.vercel.app.

If you've got an Access database that's holding your business together and you're wondering what moving it would involve, send me a short description of what's in it and what you need it to do. I'll tell you how I'd approach it.

Publishing notes (not part of the article)

Target keyword: migrate Microsoft Access database to web app

Secondary phrases used naturally in the text: Access migration, Microsoft Access database, move Access to a web app, CRM data migration.

Suggested Medium tags (5): Microsoft Access, Data Migration, Small Business, CRM, Software Development

Canonical link plan:

  1. Publish the article on your own site first, for example at https://ayman-atif.vercel.app/blog/migrate-microsoft-access-database-to-web-app/, and add it to sitemap.xml, feed.xml and the blog index.
  2. Wait until Google has indexed it (check with URL Inspection in Search Console).
  3. Bring it into Medium with Import a story (medium.com/p/import) using your site URL. Medium then sets the canonical link to your page automatically. If you paste it in by hand instead, open the story's More settings > Advanced settings and set the canonical link to your page's URL before publishing.
  4. Keep the links to /work/crm-data-migration/ and the homepage in the Medium version, so readers (and search engines) find their way back to your site.
📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.