I try to import content from a .csv file into article nodes of a fresh D9 install using Migrate, Migrate Plus, Migrate Tools, Migrate csv source and Migrate File (extended)

My article content type has a field_article_media_image expecting a media image item.

When I run the migration, the articles are created correctly BUT the field_article_media_image is still empty. I see the image has been imported in the filesystem, but created as a file, not as a media item (not present in the media tab) and it is not linked to the article.


id: import_articles
label: Import articles
migration_group: import_articles_group

  plugin: entity:node

    DESTINATION_PATH: 'public://migrations/articles/images/'
  plugin: 'csv'
  path: 'migrations/articles/articles.csv'
  delimiter: ';'
  enclosure: '"'
  header_offset: 0
    - id
      name: id
      label: 'Id'
      name: title
      label: 'Title'
      name: body
      label: 'Body'
      name: field_article_media_image
      label: 'Image'
  title: title
  body/value: body
    plugin: default_value
    default_value: 'basic_html'
    - plugin: image_import
      source: field_article_media_image
      destination: constants/DESTINATION_PATH
      title: title
      skip_on_error: true
    - plugin: log
    plugin: default_value
    default_value: article

The log gives no error. Am I missing something or am I doing something wrong?


After what @Joseph commented, I tried this code:

        source: field_article_media_image
        plugin: entity_lookup
        entity_type: media
        bundle: image
        bundle_key: bundle
        value_key: 'name'
        access_check: 0

Everything is working now, I think value_key needed quotes, and maybe access_check had to be set to false.

2 Answers 2


How your article is related to the image is actually like this:

Article (node) -> Image (media) -> File (file)

So there are actually three migrations you have to do, assuming you're not doing anything special and just doing vanilla migrations.

  • The first migration will be to a File entity. The destination of this migration is entity:file which will migrate the information to the file_managed table. This is what migrates file metadata, like where it is in the file system, when it was changed, when it was modified, etc.

  • The second migration will be to a Media entity. The destination of this migration is entity:media with bundle image, which will create a media entity of the file. This migration is usually 1:1 with the file it's representing. This is the entity that should be related to by other entities in the system. You do a migrate_lookup on the File migration using that file's ID.

    • I believe this is the migration you're missing.
  • The last migration will be your Article migration, which is your article data from your CSV (the migration you wrote). You'll need to do a migrate_lookup on the media migration using the file's ID for field_article_media_image.

  • In the meantime, I managed to import the images as Media entities (using drupal/media_library_importer). Can I go directly to the last migration? The title for the Media item is a unique key I've got in my .csv
    – laurent
    Nov 10, 2021 at 15:59
  • @laurent If you used tools other than Migrate API to migrate Media, your article migration cannot use the migration_lookup plugin to link article to media. But you can create a process plugin and use that column in your CSV to find the correct media entity in the DB using Entity API.
    – Joseph
    Nov 10, 2021 at 16:32
  • In Migrate Plus, the plugin entity_lookup seems to be doing just what I want, the example provided is hooking nodes to users entities, I don't know how to transpose to media entities, but that does not sound overly complicated . I'm new to Drupal, so if I can avoid writing a plugin...
    – laurent
    Nov 10, 2021 at 16:47
  • 1
    @laurent entity_lookup can do what I described. You just need to configure it to point to the right entity_type ("media"), bundle ("image"), bundle_key ("bundle"), and most importantly value_key - the machine name of the field in your media entity that holds the value that coincides with the value in your articles CSV.
    – Joseph
    Nov 10, 2021 at 17:29

What I did that work:

  plugin: migration_lookup
  migration: previous_migrate_media_image
  source: node_uid
  plugin: skip_on_empty
  method: row
  message: 'nid is missing'

    - previous_migrate_user
    - previous_migrate_media_image
  optional: { }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.