By Greg Nowak. Last reviewed 31 October 2026.
A Drupal import can finish without errors and still leave a business with unusable content: articles without authors, documents nobody can find, or customer records with the wrong access. Moving the rows is only part of the job.
Whether you are replacing a legacy CMS, consolidating a forum, or importing operational data, the useful starting point is a migration plan that editors, developers, and the business owner can all check. Here is how to build one before committing to a launch date.
Decide what belongs in the new site
Inventory the content, accounts, categories, files, comments, languages, permissions, and URLs. Give each group a destination: migrate, transform, archive, or discard. A historical record may need to remain accessible without becoming editable Drupal content.
Settle account decisions separately from author attribution. Preserving an author's name does not necessarily require giving a former user an active login. Likewise, old role names should not automatically become permissions on the new site.
For an agency brief, ask for four deliverables: an approved mapping, repeatable migration code, a validation report, and a launch runbook. Give someone on the client side authority to resolve content questions.
Write a mapping people can review
A useful mapping connects each source field to its destination, transformation rule, exception handling, and acceptance check. Replace instructions such as “clean up dates” with an explicit rule covering the source timezone and missing values.
| Source item | Decision to document | Acceptance check |
|---|---|---|
| Legacy record ID | Keep a stable, unique migration key | Reimport does not create duplicates |
| Author reference | Link to an account or preserve attribution | Missing authors follow an agreed rule |
| Body content | Transform markup and embedded links | Representative pages render correctly |
| Documents and images | Map storage, media, and access | Files open with the intended permissions |
| Legacy URL | Choose the replacement page or archive | Important old links reach the right content |
Choose an inspectable source
CSV suits finite, reasonably flat datasets that business owners need to review. Migrate Source CSV provides a CSV source plugin for Drupal's Migrate API. Use durable IDs from the source system rather than spreadsheet row numbers, which can change when an export is regenerated.
A read-only SQL extract can suit complex relationships; JSON, XML, or an API may be more natural for another system. Keep an untouched, dated extract and record encoding, delimiters, and extraction rules. Restrict access to personal data and use masked test copies where possible.
If both systems must keep changing indefinitely, define ownership and conflict rules as an integration project. A scheduled import alone does not settle those questions.
Build small migrations in dependency order
Drupal's Migrate API separates work into source, process, and destination: retrieve records, transform them, then save them. Its map tables connect source IDs to destination IDs, allowing later migrations to resolve relationships.
Build the destination content model first. Then import prerequisites before the records that reference them: for example, users and categories before articles, and files before media that uses them. Declare dependencies rather than relying on someone's remembered command order.
Migrate Plus adds configuration-based migrations, shared migration groups, and JSON/XML source support. Select compatible module versions through the project's Composer workflow; copying an old tutorial's dependency list is a poor starting point.
Rehearse imports, updates, and rollback
Start in an isolated environment with awkward records: missing authors, duplicate titles, multilingual text, broken file references, and embedded markup. With compatible Migrate Tools installed, the working commands include:
drush migrate:status
drush migrate:import migration_id --limit=50
drush migrate:messages migration_idReplace migration_id with the migration's actual ID. Inspect the sample before rehearsing rollback:
drush migrate:rollback migration_idSome migration commands also exist in Drush itself, but feature support differs. Confirm the project's command provider and options with drush help migrate:import.
Test a second import explicitly. Decide which fields the source owns and which editors may change. For incremental imports, Drupal supports high-water marks or change tracking; a high-water value based only on increasing IDs will miss edits to older records. Agree how source deletions are handled too.
Rollback is a development tool, not a full restore strategy. Keep verified database and file backups. Drupal's execution guidance also recommends controlling expensive processing during imports. Plan search indexing and outbound notifications deliberately.
Make acceptance checks match business use
Reconcile source totals with imported, excluded, skipped, and failed records. Explain differences in an exception log; matching totals alone cannot prove the relationships are correct.
Have editors inspect representative pages and operations staff test access, search, and workflows. Check private files while signed out as well as signed in. Follow important legacy URLs and internal links. Record a named owner for each unresolved issue and decide which issues block launch.
Launch with a clear stopping point
The runbook should name the source freeze time, backup owner, import order, validation checks, redirect activation, indexing work, and sign-off owner. Measure a full rehearsal so the cutover window includes validation and recovery time.
Agree when to stop and restore if checks fail. If the old system remains writable, document how late changes reach Drupal. At handover, retain source extracts securely alongside mappings, code, logs, exceptions, and approvals.
If the difficult part is coordinating legacy data, editorial decisions, and an agency delivery team, Greg can help turn that scope into an executable plan. Discuss your Drupal migration with Greg—bring a sample export, the intended content model, and any launch constraints.
Related on GrN.dk
- Drupal 7 Content Type Export and Import: A Practical Legacy Guide
- Drupal Relaunch: What Happens to Your Content and Old URLs?
- MySQL Zero-Date Import Errors: A Safer Fix for Legacy Data
Need help with this kind of work?
Discuss your Drupal migration with Greg Get in touch with Greg.