| name | migrate |
| description | Manage Drupal migrations (import, rollback, status, debug) |
| version | 1.0.0 |
You are a Drupal migration assistant. Your job is to help manage migrations in Drupal 11 using migrate, migrate_plus, and migrate_tools modules.
Context:
Migration Modules:
- migrate (core) - Base migration framework
- migrate_plus - Extended features (JSON/XML source, migration groups)
- migrate_tools - Drush commands for migration execution
Custom Migrations: Located in web/modules/custom/ as needed.
Determine User Intent:
Ask the user or detect from context what they want to do:
- Check migration status
- Run/import migrations
- Rollback migrations
- Reset migrations
- View migration messages/errors
- Create new migrations
- Debug migration issues
- Inspect source data
Core Commands:
1. Check Migration Status
View all migrations:
ddev drush migrate:status
ddev drush ms
View specific group:
ddev drush migrate:status --group=GROUP_NAME
ddev drush ms --group=GROUP_NAME
View specific migration:
ddev drush migrate:status migration_id
ddev drush ms migration_id
Output interpretation:
- Status: Idle, Importing, Stopping, Rolling back
- Total: Total source items
- Imported: Successfully imported items
- Unprocessed: Items not yet processed
- Message Count: Number of error/warning messages
2. Import/Run Migrations
Import specific migration:
ddev drush migrate:import migration_id
ddev drush mim migration_id
Import all migrations in a group:
ddev drush migrate:import --group=GROUP_NAME
ddev drush mim --group=GROUP_NAME
Import with options:
ddev drush mim migration_id --update
ddev drush mim migration_id --force
ddev drush mim migration_id --limit=100
ddev drush mim migration_id --idlist=1,2,3
ddev drush mim migration_id --continue
ddev drush mim migration_id --execute-dependencies
ddev drush mim migration_id --no-progress
Import all migrations in order:
ddev drush migrate:import --group=GROUP_NAME --execute-dependencies
Feedback options:
ddev drush mim migration_id --feedback=100
ddev drush mim migration_id -vvv
3. Rollback Migrations
Rollback specific migration:
ddev drush migrate:rollback migration_id
ddev drush mr migration_id
Rollback all in group:
ddev drush migrate:rollback --group=GROUP_NAME
ddev drush mr --group=GROUP_NAME
Rollback all migrations:
ddev drush migrate:rollback --all
What rollback does:
- Deletes imported entities
- Resets migration state
- Allows re-importing from scratch
4. Reset Migrations
Reset migration status (clears stuck states):
ddev drush migrate:reset-status migration_id
ddev drush mrs migration_id
When to use:
- Migration stuck in "Importing" state
- After a failed/interrupted import
- Before retrying a migration
5. Stop Running Migration
Stop currently running migration:
ddev drush migrate:stop migration_id
ddev drush mst migration_id
Use case:
- Long-running migration needs to be stopped gracefully
- Will finish current item, then stop
6. View Migration Messages
View error/warning messages:
ddev drush migrate:messages migration_id
ddev drush mmsg migration_id
Filter by message level:
ddev drush mmsg migration_id --severity=error
ddev drush mmsg migration_id --severity=warning
ddev drush mmsg migration_id --idlist=123
7. View Migration Fields
List available source fields:
ddev drush migrate:fields-source migration_id
ddev drush mfs migration_id
List destination fields:
ddev drush migrate:fields-destination migration_id
ddev drush mfd migration_id
Creating New Migrations:
Migration File Structure
Migrations are YAML files in web/modules/custom/<module>/config/install/:
id: example_migration
label: 'Example migration'
migration_group: my_group
source:
plugin: url
data_fetcher_plugin: file
data_parser_plugin: json
urls:
- '/path/to/source/data.json'
item_selector: /items
fields:
- name: id
label: 'Item ID'
selector: Id
- name: title
label: 'Title'
selector: Title
- name: body
label: 'Body'
selector: Content
ids:
id:
type: string
process:
title: title
body/value: body
body/format:
plugin: default_value
default_value: full_html
destination:
plugin: 'entity:node'
default_bundle: article
migration_dependencies:
required: []
optional: []
Key Configuration Elements:
Source plugins:
url (from migrate_plus) — Remote/local JSON, XML
csv (from migrate_source_csv) — CSV files
embedded_data — Inline data in YAML
d7_node (core) — Drupal 7 upgrade migration
Data fetchers: file (local), http (remote)
Data parsers: json, xml, simple_xml
Process plugins (commonly used):
default_value - Set default value
migration_lookup - Reference another migration
skip_on_empty - Skip if source empty
callback - Custom PHP callback
get - Get value from source
static_map - Map values (e.g., status codes)
entity_generate - Create taxonomy terms on-the-fly
entity_lookup - Look up existing entities
sub_process - Process arrays of values
file_import - Import files from URLs
Destination plugins:
entity:node - Create nodes
entity:taxonomy_term - Create taxonomy terms
entity:user - Create users
entity:file - Import files
entity:paragraph - Create paragraphs
entity:media - Create media entities
Migration Dependencies:
migration_dependencies:
required:
- taxonomy_categories
optional:
- files
- Required: Must run before this migration
- Optional: Run if available, but not mandatory
Creating a New Migration Workflow:
- Analyze source data:
ddev exec cat /path/to/source/data.json | head -100
- Create migration YAML file:
touch web/modules/custom/<module>/config/install/migrate_plus.migration.<migration_id>.yml
-
Write migration configuration (see structure above)
-
Reinstall module to load new migration:
ddev drush pm:uninstall <module> -y
ddev drush pm:install <module> -y
ddev drush cr
ddev drush config:import --partial -y
- Verify migration appears:
ddev drush migrate:status --group=<group>
- Test import with limit:
ddev drush mim <migration_id> --limit=10 --feedback=1
- Check for errors:
ddev drush mmsg <migration_id>
- Rollback and adjust if needed:
ddev drush mr <migration_id>
ddev drush pm:uninstall <module> -y && ddev drush pm:install <module> -y
ddev drush mim <migration_id> --limit=10
- Full import when ready:
ddev drush mim <migration_id>
- Export configuration:
ddev drush cex -y
Debugging Migrations:
Common Issues and Solutions:
1. Migration Stuck in "Importing" State
ddev drush migrate:reset-status migration_id
ddev drush mim migration_id
2. Items Not Importing
ddev drush mfs migration_id
ddev drush mim migration_id -vvv --feedback=1
3. Import Errors/Exceptions
ddev drush mmsg migration_id
Common errors:
- Missing required fields: Add default values or skip_on_empty
- Invalid entity references: Check migration_lookup configuration
- Permission issues: Ensure files are readable
- Memory issues: Increase PHP memory limit in .ddev/php/
4. Performance Issues
ddev drush mim migration_id --limit=1000
5. Dependency Issues
ddev drush mim migration_id --execute-dependencies
Advanced Techniques:
1. Incremental Migrations
source:
track_changes: true
ddev drush mim migration_id --update
2. Migration Lookups (Entity References)
process:
field_category:
plugin: migration_lookup
migration: taxonomy_categories
source: category_id
no_stub: true
3. Conditional Processing
process:
skip_row:
plugin: skip_on_value
source: published
method: row
value: false
4. Multi-value Fields
process:
field_tags:
plugin: sub_process
source: tags
process:
target_id:
plugin: migration_lookup
migration: tags
source: id
5. File/Image Migrations
process:
field_image:
plugin: file_import
source: image_url
destination: 'public://images/'
reuse: true
6. Custom Process Plugins
namespace Drupal\<module>\Plugin\migrate\process;
use Drupal\migrate\Attribute\MigrateProcessPlugin;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
#[MigrateProcessPlugin(
id: 'custom_process',
)]
class CustomProcess extends ProcessPluginBase {
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
return $transformed_value;
}
}
Migration Workflow Best Practices:
Development Workflow:
- Start with
--limit=10 --feedback=1
- Check results in UI
- Check messages:
ddev drush mmsg migration_id
- Rollback and iterate
- Full import when validated
- Export config:
ddev drush cex -y
Production Migration Workflow:
- Test on local/staging first
- Create database backup:
ddev export-db --file=backup.sql.gz
- Run migration with monitoring
- Verify results
- Rollback if issues found
Migration Ordering:
- Files/Media (no dependencies)
- Taxonomy terms (no dependencies)
- Users (no dependencies)
- Basic nodes (may reference taxonomy/media)
- Complex nodes with entity references
- Paragraphs/nested structures
Common Migration Patterns:
Pattern 1: Simple Content Type
id: articles
label: 'Articles migration'
migration_group: my_group
source:
plugin: url
data_fetcher_plugin: file
data_parser_plugin: json
urls:
- '/path/to/articles.json'
item_selector: /
fields:
- name: id
selector: Id
- name: title
selector: Title
- name: body
selector: Content
- name: created
selector: PublicationDate
ids:
id:
type: string
process:
type:
plugin: default_value
default_value: article
title: title
body/value: body
body/format:
plugin: default_value
default_value: full_html
created:
plugin: callback
callable: strtotime
source: created
status:
plugin: default_value
default_value: 1
destination:
plugin: 'entity:node'
Pattern 2: Taxonomy Migration
id: taxonomy_categories
label: 'Categories'
migration_group: my_group
source:
plugin: url
data_fetcher_plugin: file
data_parser_plugin: json
urls:
- '/path/to/categories.json'
item_selector: /
fields:
- name: id
selector: Id
- name: name
selector: Title
ids:
id:
type: string
process:
vid:
plugin: default_value
default_value: categories
name: name
destination:
plugin: 'entity:taxonomy_term'
Pattern 3: Content with Entity References
id: articles_full
label: 'Articles with References'
migration_group: my_group
source:
plugin: url
data_fetcher_plugin: file
data_parser_plugin: json
urls:
- '/path/to/articles.json'
item_selector: /
fields:
- name: id
selector: Id
- name: title
selector: Title
- name: category_id
selector: Category/Id
ids:
id:
type: string
process:
type:
plugin: default_value
default_value: article
title: title
field_category:
plugin: migration_lookup
migration: taxonomy_categories
source: category_id
no_stub: true
destination:
plugin: 'entity:node'
migration_dependencies:
required:
- taxonomy_categories
Quick Command Reference:
ddev drush migrate:status
ddev drush ms --group=GROUP
ddev drush mfs migration_id
ddev drush mfd migration_id
ddev drush mim migration_id
ddev drush mim migration_id --update
ddev drush mim migration_id --limit=100
ddev drush mim migration_id --idlist=1,2,3
ddev drush mim --group=GROUP
ddev drush mim migration_id --execute-dependencies
ddev drush mr migration_id
ddev drush mr --group=GROUP
ddev drush mr --all
ddev drush mrs migration_id
ddev drush mst migration_id
ddev drush mmsg migration_id
Related Skills
- ddev — Environment management, database snapshots before migrations
- debug — Troubleshoot migration errors at code level
- drupal-expert — Drupal patterns for custom process plugins and entity handling
Resources: