DevOps · Devops

Acumatica Database Migration Strategy

Acumatica Database Migration Strategy is the Acumatica operations topic that you only get good at by doing it badly a few times.

John Kihiu12 min read

Acumatica's schema is not something you own in the way you own a hand-rolled application database — most tables are defined by the platform, and your customizations add to it through DAC extensions with Usr-prefixed fields. A database migration strategy for Acumatica is therefore really two different problems: migrating the platform itself between major versions, and safely evolving the schema additions your customizations own.

Platform version upgrades

Acumatica major version upgrades (an R1/R2 release cycle jump, e.g. 2024 R2 to 2025 R1) run through the built-in upgrade process — a database backup, the target build's upgrade scripts applied in sequence, and a post-upgrade customization compatibility pass. Acumatica documents which upgrade paths are supported directly (you generally cannot skip more than a couple of release cycles in one hop), so the real migration strategy question is sequencing: upgrade a copy of production first, run your full customization suite against it, and only then schedule the live upgrade window.

Snapshot before every upgrade attempt

The upgrade process modifies the database in place. If a customization fails to recompile against the new build, you need a fast path back to the pre-upgrade state — a full database backup (or, on Azure SQL, a point-in-time restore point) taken immediately before the upgrade starts, not the nightly backup from nine hours earlier.

Your own schema additions

Fields you add via PXDBString, PXDBInt, and similar attributes on a DAC extension become real columns on publish — Acumatica's customization engine issues the ALTER TABLE for you when the project compiles. This is convenient until you need to change a field's type, rename it, or backfill a default for existing rows: none of that is handled automatically, and a rename effectively means "add a new field, migrate data, remove the old field" across a release, not an atomic operation.

SQL · BACKFILL AFTER A NEW USR FIELD
-- After publishing a customization that adds UsrRiskTier to Customer,
-- backfill existing rows before making the field required in the UI.
UPDATE cr
SET cr.UsrRiskTier = CASE
    WHEN c.CreditLimit > 1000000 THEN 'LOW'
    WHEN c.CreditLimit > 100000  THEN 'MEDIUM'
    ELSE 'HIGH'
END
FROM CRLocationExt cr
INNER JOIN Customer c ON c.BAccountID = cr.BAccountID
WHERE cr.UsrRiskTier IS NULL;

Import Scenarios for one-time data migration

For moving data into Acumatica from a legacy system — not schema changes, but actual record migration — the built-in Import Scenarios (SM206036) and Import by Scenario functionality handle CSV/Excel-sourced data with field mapping and business-logic validation running through the same PXGraph the UI uses, so you get the same validation a user would hit typing into the screen. This is the right tool for a one-time cutover load; it is the wrong tool for ongoing schema evolution, which belongs in the customization/DAC-extension path above.

Staging and rollback for schema changes

Because customization-driven schema changes apply automatically on publish, your rollback plan cannot rely on "just don't publish it" once it's live — un-publishing a project does not reliably drop the columns it added. The safer sequence is: test the schema-changing customization against a restored copy of production first, and treat the live publish as the point of no easy return. If a field needs to be removed later, do it as its own deliberate change with a backup taken immediately before.

Keeping dev, test, and production schemas in sync

The most common migration failure in practice is not a botched upgrade — it's a customization published directly to production that was never applied to the lower environments, so the next developer's local database no longer matches reality. Publishing every schema-affecting customization through the same package to dev, then test, then production, in that order, and refreshing lower environments from a production backup on a regular cadence, keeps this from compounding.

Wrapping up

Treat platform upgrades and customization schema changes as two separate migration disciplines with one shared rule: back up immediately before the change, test the restore path before you need it, and never let a schema change reach production without having been proven against a real copy of the data first.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.