Sql Migration map returns nonsensical destination ids when looking up against a source id row that failed or was ignored.

Created on 19 November 2019, almost 5 years ago
Updated 20 September 2024, 8 days ago

Problem/Motivation

The changes I made to the D7 source while working on #3008028: Migrate D7 i18n menu links caused an unexpected and unrelated error,

[error] Attempt to create a field field_text_plain_filtered that does not exist on entity type node. (/opt/sites/d8/core/modules/field/src/Entity/FieldConfig.php:312)

while running d7_field_instance_label_description_translation migration. That migration should not be trying to save to a field that does not exist and it even has a skip_on_empty to prevent that.

There are several issue already for improvements and fixes to migration_lookup but I didn't see this particular problem there.

  exists:
    -
      plugin: migration_lookup
      migration: d7_field_instance
      source:
         - entity_type
         - objectid
         - type
    -
      plugin: skip_on_empty
      method: row

However, the skip does not skip when the field does not exist. When the field does not exist migration lookup returns an array with 3 elements, all NULL and thus there is no SkipRowException.

Proposed resolution


Option 2) Alter all the migration yml that have a migration_lookup where an array of NULL might be returned and that is followed by a skip_on_empty to include a callback process with array_filter. I guess that will work.

Discussed in migrate meeting and it was decided to implement Option 2. Option 1 would mean the migration_lookup needs to be deprecated and that is for another day as there are several things to improve in that plugin.

Remaining tasks

Write a patch
Add some tests
Review

User interface changes

N/A

API changes

Migration lookup returns NULL instead of an array where all elements are NULL

Data model changes

Release notes snippet

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Migration 

Last updated 1 day ago

Created by

🇳🇿New Zealand quietone

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7 updated deps
    last update about 1 year ago
    Composer error. Unable to continue.
  • last update about 1 year ago
    Composer error. Unable to continue.
  • last update about 1 year ago
    Patch Failed to Apply
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & sqlite-3.27
    last update about 1 year ago
    Composer error. Unable to continue.
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.2 & sqlite-3.34
    last update about 1 year ago
    Composer error. Unable to continue.
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.2 & pgsql-14.1
    last update about 1 year ago
    Composer error. Unable to continue.
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update about 1 year ago
    Composer error. Unable to continue.
  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & pgsql-14.1
    last update about 1 year ago
    Composer error. Unable to continue.
  • last update about 1 year ago
    Patch Failed to Apply
  • last update about 1 year ago
    Patch Failed to Apply
  • Status changed to RTBC about 1 year ago
  • 🇬🇷Greece vensires

    In my D9 installation this patch played perfectly! I set it as RTBC.

  • last update about 1 year ago
    30,006 pass, 14 fail
  • @vensires opened merge request.
  • 🇬🇷Greece vensires

    The only thing failing is the change of the patch from #22 to the /core/modules/migrate_drupal/tests/fixtures/drupal7.php file.
    In this MR I opened, I haven't added this change.
    Is that actually needed? From what I may understand, I think not.

  • Status changed to Needs work about 1 year ago
  • 🇺🇸United States mikelutz Michigan, USA

    The change to the test fixture is what surfaces the bug to the core test suite, so the tests fail. This is not ready to commit. There are 14 failed tests because the changes in #22 aren't backwards compatible. Fixing the bug in this way would break existing migrations that have already implemented workarounds. This needs more work to allow opting into the fix and a warning that migrations should be updated to use the fix or they will break in the next major version.

  • 🇬🇧United Kingdom james.williams

    I've had a go at allowing this new behaviour to be optional (disabled by default). So when using the migration_lookup process plugin, a 'skip_unmigrated' option can be passed.

    From reading above, it looks as though we might ultimately want the option to be enabled by default, but I'm just being conservative for now - and presumably tests will pass with this as no migrations will actually be using it yet. But sure, the next step could be to invert that, and update existing migrations and add the warning.

    I'm also not sure about the BC implications. I've added an optional parameter to some methods to pass the configuration along. I'm not sure if there's a better way. Presumably we could just target 11.x without any backporting, but with a change record?

  • last update about 1 year ago
    Custom Commands Failed
  • 🇬🇧United Kingdom rossb89 Bristol

    Thanks @james.williams This looks promising but unfortunately I encountered an issue when using Migrate Tools:

    Fatal error: Declaration of Drupal\migrate_tools\IdMapFilter::lookupDestinationIds(array $source_id_values): array must be compatible with Drupal\migrate\Plugin\MigrateIdMapInterface::lookupDestinationIds(array $source_id_values, bool $skip_unmigrated = false)

    In @migrate_tools/src/IdMapFilter.php:195@ there is a declaration of

      public function lookupDestinationIds(array $source_id_values): array {
        $map = $this->getInnerIterator();
        \assert($map instanceof MigrateIdMapInterface);
        return $map->lookupDestinationIds($source_id_values);
      }
    

    which would also need to be modified to handle the extra parameter, to work in conjunction with this patch.

  • 🇬🇧United Kingdom joachim
Production build 0.71.5 2024