Problem/Motivation
Similar to #3096951: d7_node migration should have dependency on d7_node_title_label migration and #3097327: d7_node_title_label migration plugin incorrectly generating base_field_override for every node type, even those that don't have an overridden title label.
Right now there is only one:
- "View Modes" (
d7_view_modes) migration - "Field configuration" (
d7_field) migration - "Field instance configuration" (
d7_field_instance) migration - "Field formatter configuration" (
d7_field_formatter_settings) migration - "Field instance widget configuration" (
d7_field_instance_widget_settings) migration
… rather than one of those per entity type + bundle.
This is harder to understand, and harder to debug.
Furthermore, just like #3097314: d7_comment migration should have dependency on d7_comment_entity_display, same for d7_custom_block + block_content_entity_display, the concrete entity migration not having a dependency on the above configuration makes it harder to compare the data on the destination D8 site with the source D7 site, because equivalent formatters and widgets will be used.
Proposed resolution
- Add a deriver to each of the aforementioned migration plugins.
- Add
optionalmigration dependencies. to the corresponding content entity migrations.
Comments
Comment #2
wim leersNot fully working yet, but this gets us pretty far along the way :)
Comment #3
wim leersThis is by far the biggest TODO. Right now, this only is able to generate derivatives per
Nodebundle. It can't do it yet for other entity types.I think a viable strategy here is to create a derivative per node type (
Nodebundle), but for all other entity types, create one derivative per entity type.Comment #4
quietone commentedI've looked at this over the past days (while on holiday) and every time I am not convinced this is needed. I am happy to be wrong about that and maybe I still have blinders on because of #2208401: [META] Remaining multilingual migration paths.
Comment #5
webchickSpeaking from a user/developer experience POV, I like it because it allows me to divide my migration pain into more manageable chunks.
If I were to migrate Drupal.org to D8, for example, we have, let's see...
- ~85,500,000 nodes
- ~8,000,000 comments (and that's just the published ones :P)
- ~2,000,000 users
...and so on.
That's an extreme example. :) But even in my crappy D7 blog, this would allow me to focus on one or two smaller areas of the migration (e.g. custom blocks, or pages, for which I only have a few) prior to getting into the stuff with more hard-core dependencies that need thought/work (e.g. a couple blog posts have the PHP filter, oh noes), and still experience early "hey things are happening!" success.
Comment #6
gabesulliceRefined the patch in #2 so that it will be easily used for other entity types and bundles. I think I lost some of the work to establish proper dependencies that was in #2. I'll restore that tomorrow.
Comment #7
wim leersComment #8
gabesulliceOkay, this now breaks the field configuration migration out into separate migrations per entity type and sets up the appropriate dependencies for nodes, terms and field instances.
Next up: views modes, field formatter and field widget configurations.
Comment #9
gabesulliceAlright this patch completes the derivation of all migrations listed in the issue summary, it also adds the
d7_view_modes,d7_field_formatter_settings, andd7_field_instance_widget_settingsmigrations as optional dependencies of thed7_nodeandd7_commentmigrations as this information was previously missing.Comment #10
gabesulliceThis should clean up some undefined index errors and a copy pasta problem with an
assertthat was mucking up the watchdog logs.I think there are still some weird dependency things going one where certain derived node migrations are depending on all of the derived view mode migrations instead of just depending on the ones that it "cares" about.
Comment #11
gabesulliceFixes the view mode thing.
Comment #12
heddnI'm not sure that replicating like rabbits the various derivers helps anything in core. If someone wanted to add this in contrib (migrate_upgrade???) and incubate it there for a while, there might be some benefit. But doing this in core for core's sake wouldn't really help much at this point.
Comment #13
quietone commentedYes, that is what has been bothering me about this work, that is, core does not need this. So let's move it to contrib and keep this valuable work. I have no suggestion for where to put it and mgrate_upgrade is definitely a possibility. I would like to mention that there is an issue to move migrate_upgrade to drush itself #2709537: Move Drush commands into Drush itself. Maybe that will influence the decision?
Comment #14
wim leers@heddn & @quietone: I think we heard you loud and clear. Thanks for your patience, your guidance, and your thoughtful feedback! Much appreciated 😊
So, this then becomes a question about which contrib module to move it into.
migrate_upgradedoesn't really make sense to me, because it's 100% about Drush. This is absolutely independent of Drush.To @quietone's point: #2709537: Move Drush commands into Drush itself and the sibling issue https://github.com/drush-ops/drush/issues/2140 were opened in 2016. Drush maintainers said "sure, if it comes with tests and a maintainer". I don't think that's suddenly going to happen?
Comment #15
alisonSo, migrate_plus?
Comment #16
heddnAll things related to upgrading from a previous version of drupal, without regard to if that means drush or web ui or whatever should really land in migrate upgrade. So while drush is the only mechanism in migrate upgrade, that doesn't mean someone could add a web ui.
Comment #17
wim leersAha! That is really good to know!
So then the question becomes: as a maintainer of Migrate Upgrade, would you accept this patch in Migrate Upgrade?
Comment #18
heddnYes.
Implementation details... we'd want to have an additional flag to the drush command to use this option. Or maybe an option to turn it off. Some way to flag it.
Comment #19
wim leersBut … would it be a thing that only works for the drush command? I imagined it'd be a
hook_migration_plugins_alter()implementation inmigrate_upgrade?Comment #20
heddnIt would work however we wanted it to work. There could be a state flag or something. It could be developed initially for drush but later made available for a web ui. 🤷♂️
Comment #21
damienmckennaDo this and the similar issues need change notices?
Comment #22
mikelutzI would like to close this, but I'm setting to nw because it needs a follow up issue filed in migrate upgrade. Once that is done, this should be closed won't fix and the new issue linked.
Comment #23
heddnAlternatively, you can just move tickets from one project queue to another without closing them.
Comment #24
quietone commentedI prefer the alternative and will take the action to move this to Migrate Upgrade.
Comment #25
wim leers+1 for moving — that way we don't lose the comment history :)
Comment #26
wim leersRebase because #3097327: d7_node_title_label migration plugin incorrectly generating base_field_override for every node type, even those that don't have an overridden title label landed. (This is still a patch relative to Drupal core, not yet for
migrate_upgrade.)Comment #27
wim leersFix lots of notices.
Comment #28
wim leersFixed another notice.
Comment #29
wim leersIf
optionalmigration dependencies include both:… then it's impossible to deduce which configuration must be migrated prior to being able to migrate + view those entities immediately after running the migration.
So… this makes many more migration dependencies
required. Which in turn triggered the need for a change in\Drupal\migrate\Plugin\Migration::checkRequirements()— I've left a detailed comment explaining the rationale.Ideally, we'd have a way to know which migrations are necessary for the migration of entities of a certain entity type + bundle. Then we would have an alternative way to deciding the combinations of migrations to run together for it to make sense to a site builder. That's a much bigger conversation to have, and at least this helps to keep the conversation going.
Comment #30
wim leersAlso, for things to make sense for the site builder, the solution that was committed in #3097327: d7_node_title_label migration plugin incorrectly generating base_field_override for every node type, even those that don't have an overridden title label is inadequate. It was a step forward, but for this to be truly user-friendly, we need to bring back #3097327-4: d7_node_title_label migration plugin incorrectly generating base_field_override for every node type, even those that don't have an overridden title label.
This does that.
Comment #31
wim leersStill to do: the equivalent of #30 for
node_type,comment_type, and more. Ideally we do this in a generic way 🤞Comment #32
huzookaComment #33
huzookaPatch #30 still relative to Drupal core.
To be able to apply it on core, you have to apply:
Comment #34
huzookaTaxonomy term (and user) derivatives should be fine.
Still @TODO: node_type, comment_type.
Comment #35
huzookaAdding the missing WIP patch (still on top of core + the patches from #33).
Comment #36
huzookaThis patch fixes the taxonomy vocabulary migrate source plugin issue we have in #35, and a regression of the comment migrations.
Comment #37
huzookaComment #38
huzookaDrupal 7 node type migrations are derivered migrations.
Comment #39
huzookaThese try / catch blocks are really important: without these, if we don't have any fields to migrate, we would see exceptions instead of our Drupal site 😶.
Since
D7NodeDeriveralmost fulfilled my needs (explode thed7_node_typemigration to derived migrations), I modified this class instead of adding a new one.These
$dependecy_indexvars weren't checked before, these are now fixed as well 🙂Comment #40
huzookaComment #41
huzookaThis is where I had faulty logic:
For comment derivatives, both
$entity_type_suffixand$entity_type_and_bundle_suffixwas:comment, and so this class checked onlyd7_field_instancefor comment:$required_migration_idswasinstead of
Comment #42
huzookaComment #43
huzookaComment #44
huzookaComment #45
wim leersFYI: #44 is now relative to #2746541-350: Migrate D6 and D7 node revision translations to D8.
Comment #46
huzookaComment #47
heddnI'm torn w/ this issue. I can see some (small?) benefit for it for custom migrations. There's obviously interest in seeing it move along too. But from my personal experience, I don't quite get the large DX that others seem to find in splitting these things up. I'm willing to take and commit anything that the community wants if things like tests, etc are present. But right now I'm struggling w/ understanding why this is needed.
I think that's also why this is in contrib land at the moment too. Which means that we are stuck w/ nasty migration_plugin_alters, which I really don't like as they are hard to maintain for the long term. What are the names of the resulting migration yml files that get spit out when this patch is applied? I'm mainly interested in the field config migrations, rather then the other more content related migrations.
Comment #48
xjmFWIW the dependency mapping and data integrity use cases of this seem really valuable to me, although I totally understand the concerns about maintenance burden.
Comment #49
wim leersThe improved DX was described by @webchick in #5:
(We discussed this at length in Migration meetings in Slack before.)
Comment #50
heddnre #48: I'm hopefully not playing dumb, that isn't my intention. What data integrity issues? I don't see it mentioned anywhere in this issue. Data dependency between related migrations is usually handled successfully by the migrate_lookup plugin. If there are specific cases where we have issues, we typically fix those as we find them.
re #49: There's already 150+ migration templates. If we add more derivers, we'd be looking at many more. There's nothing in the existing API that stops a site from handling these scenarios (via custom migrations) and adding more per bundle or entity type migration templates. But for the smaller sites, less can be more. I am worried that adding more derivatives, we'd be making it more complicated.
Additionally, in real life migrations the config set of migrations get run pretty rarely. A site might use the config generated migrations to build out the new site with the basic config structure. But then site builders start swapping out field collections for custom field types (or paragraphs) and combining content types, etc. Basically, lots of config changes. And at that point, you can't run the config migrations any more. You can only run the content migrations.
From the IS, we're looking at almost (maybe exclusively?) config migrations. So, I state again, I'm torn. I'm happy to go with a larger majority here, but I'm still not fully convinced in the benefit.
Comment #51
quietone commentedYes, I am torn too. I can see why it makes sense from one point of view. One thing about this that may be a problem from some is the increase in the number of tables. I recall reports of sites not being about to upgrade because of a limit on the number of tables they could have.
All up I completely agree with heddn comments and questions.
Comment #52
huzookaComment #53
huzookaComment #54
huzookaThis patch refines comment-related migrations.
The migration lookup process plugins will check the corresponding
d7_comment:node_typeandd7_comment_type:node_type</code migrations instead of all the <code>d7_commentandd7_comment_typemigrations.Comment #55
huzookaThis change adds
d7_filter_formatas a required migration dependency to every derivedd7_field_instancemigration that might need it.Comment #56
wim leers#55:
Elegant :) 👍
Let's use
in_array(…, …, TRUE)🤓I think this should be:
Comment #57
huzookaAddressing feedbacks in #56.
Comment #58
shaktik@huzooka
It's good to un-assign the issue.
Comment #59
huzooka@shaktik, thanks for reminding me, you're right!
Comment #60
wim leersThis was introduced in #43.
This is great. But it's:
- more strict than necessary: it could be more forgiving
- less informative than it could be
This improves that.
Comment #61
huzookaRe #60:
I deeply agree, I think this is the right approach!
Comment #62
huzookaFixed bugs:
We should sort both of the query results before a strict comparison.
This change makes node bundle field processes to be added only to node entity migrations.
Previously I thought this was a neat solution, but since the source entity type ID does not necessarily match the new one (e.g.
field_collection_itemis mapped toparagraphin #2911244: Field collections deriver and base migration), we cannot make such a decision until all migrations have been collected and altered.Comment #63
wim leersThis still generates
d7_comment_*:*derivatives for every node type even if the D7 source site does not have the Comment module installed.It also means that all this configuration is created even though it should not get created!
Solution:
Comment #64
huzookaThis issue happens even without this patch, because the
d7_comment_typemigration plugin uses thed7_node_typemigration source plugin.The solution is to create a separate source plugin for comment bundle migration that extends
d7_node_type, but with asource_moduleannotation set tocomment.Comment #65
wim leers@huzooka made #63 & #64 happen in #3176394: Do not migrate comment related configurations if "comment" wasn't enabled on the source site! 🥳
Comment #66
wim leersThis still needs to update the
d7_bookdependency ond7_nodeto be derived. We can't hardcode it tod7_node:book; we need to derive it for each of the values in thebook_allowed_typesvariable in D7.Comment #67
huzookaRe-rolled #62:
This new patch still applies on drupal core and it depends on:
Comment #68
huzookaThis new patch contains a lot of cleanup.
Short update:
D7NodeDeriverand merged intoD7CommentDeriverd7_field_option_translation,d7_field_instance_option_translation.ymlandd7_field_instance_label_description_translation.yml) are derived per entity type and bundle#66 is unaddressed, but imho it merit to get a standalone issue...
Comment #69
huzookaComment #70
huzookaDrupal\content_translation\Plugin\migrate\D7NodeDeriverthis this deriver does not exists – this should beDrupal\language\Plugin\migrate\D7NodeDeriver(language is the dependency of content_translation).This should be moved into a core patch (with the
Drupal\content_translation\Plugin\migrate\D7TaxonomyTermDeriverclass)Unnecessary linebreak.
Unnecessary linebreak.
This should be moved into a core patch.
This should be moved into a core patch.
This should be removed.
Comment #71
huzookaNew task(s) discovered after 9.1 core update:
I don't really see how these could be derived as well since the major part of the required (code) infrastructure is in a core issue #3051251: Existing menu links show validation issues on migration (and ALL menu links pointing to node translations are invalid).
Comment #72
huzookaAddressed #70.1, #70.3, #70.4 and #70.7
Comment #73
wim leers👏👏👏👏 Epic work, once again! 🤩
👍 Significant changes here, but all for the better. A huge method refactored to be smaller, more readable, and more maintainable — in particular thanks to the introduction of
\Drupal\comment\Plugin\migrate\D7CommentDeriver::processPluginDefinition()and\Drupal\comment\Plugin\migrate\D7CommentDeriver::updateCommentMigrationLookups().Debug leftover 🤓
👍 This is not because
d7_commentwasn't already derived; this is because now for the first time there are migration plugins dependingond7_comment:<bundle>— specificallyd7_comment_entity_translation.🤓 Needs FQCN.
👍 I didn't realize we didn't already have this! 😳
Now this is consistent with
\Drupal\comment\Plugin\migrate\source\d7\Comment.👍 It took me a moment to understand this
s— but I get it now: it's the "table alias" for the subquery (which is a virtual/ephemeral table).👍
👍
🤔 Just one Q: why the
$config['key'] ?? NULLpattern here whereas everywhere else you updated the constructor to generate a default configuration key-value pair, to ensure it is set?👍 Rather than nonsensical broad optional dependencies, the deriver will add only the relevant dependencies while deriving definitions!
👍 This is being fixed in #3187463: Fix "d7_field_option_translation" process plugin. It is working as expected, and was merely a bug in the sample source data.
🙏 Let's remove this TODO!
🙈
This does not exist.Already fixed!🤓 Debug leftover.
This restricts the generated rows to just those of the specified entity type + bundle.
🤔 But shouldn't it be possible to restrict only to
entity_type?Userdoesn't have a bundle after all. Then this if-test would be wrong!Oh, I see that you specified
d7_entity_translation_settings:user:user, and tests are passing, so evidently this is working. So: 👍🙏 A comment here would be welcome 🤓
💯 D'oh, right, this was repeating the query logic from
\Drupal\field\Plugin\migrate\source\d7\FieldInstance::query()!This is a big improvement wrt brittleness.
Overall, all changes here are a solid refactor that make this more robust/easier to maintain 👍
🤔 I'm not sure this comment is accurate, given the if-test that follows: that makes it pretty obvious that both are optional configuration for this source plugin?
👍 The first two are new.
👍 This last one is new.
Definitely debug leftover 😂
And this is a pre-existing debug leftover 😂
👍 Ah, yes, this makes more sense… defensive programming FTW!
Nits fixed in attached interdiff.
Comment #74
wim leersThis would have saved me a lot of time testing this:
Comment #75
wim leersIn testing this, I also noticed that
d7_taxonomy_vocabulary_translation(which was introduced in #3035392: Migrate vocabulary translations and taxonomy term references for Drupal 7 node translations) was not yet updated to get the necessary derivatives.Comment #76
huzookaRe #66:
It seems that the
book_allowed_typessetting does not restrict anything neither in Drupal 7 nor in Drupal 8 or Drupal 9.Even so, we can refine the migration dependencies of the
d7_bookmigration.Comment #77
huzookaThis addresses #76.
Now I'll address #73.
Comment #78
huzookaThis patch addresses the review posted in #73 and also adds the comment from #74.
Re #73:
entity_type(orbundle) restrictions. So ideally, a source plugin should handle these configs as optional configs.Comment #79
wim leersReviewed #78 in detail — no remarks.
Tested #78 with the
d7_bookmigration in a real-world test case. Works well 👍Comment #80
wim leersℹ️ This patch is no longer rolled on top of #3096951: d7_node migration should have dependency on d7_node_title_label migration nor #3097314: d7_comment migration should have dependency on d7_comment_entity_display, same for d7_custom_block + block_content_entity_display.
It still is rolled on top of #3176394-10: Do not migrate comment related configurations if "comment" wasn't enabled on the source site. That patch was committed to
9.2.x, and is hopefully still going to get committed to9.1.x.Comment #81
wim leers… and patch 🙈
This reverts 99% of
migration_dependencieschanges (and #3096951 + #3097314 also modified those in 3 migrations). It touches 6 fewer files overall.The only two dependencies additions that have not yet been reverted:
and
Removing both should be possible, but have enormous side/ripple effects for downstream code.
In any case, consider this a big leap forward to making this committable and maintainable :)
Comment #82
wim leersThis reverts the sole addition to
core/modules/taxonomy/migrations/d7_taxonomy_term.yml.Comment #83
huzookaThis patch is identical to #82 – but it can be applied after #3202462-6: [PP-1] Provide option for contrib modules to map their D6 / D7 field formatter and widget plugin IDs to the equivalent D9 plugin ID.
Comment #84
wim leers#3204986: Add documentation for d7 field source plugins landed a few weeks ago, shipped in 9.1.6 and hence this patch does not apply against https://www.drupal.org/project/drupal/releases/9.1.7. Rebased.
Comment #85
wim leers#3189880: Use square brackets syntax in sql queries broke this between
9.1.7and9.2.0-rc1.Comment #86
yash.rode commentedIf comment module is not enabled on soure site then we should not migrate d7_field: comment,
Interdiff denotes the actual change and other changes are caused because of the re-roll.
Comment #87
wim leersWe usually prefer strict equality checks, but in this case it's actually safer to not do that, because of per-DB peculiarities.
Let's change the second operand to
!$comment_module_statusor$comment_module_status == 0. See https://3v4l.org/2kf2W.Comment #88
yash.rode commentedfollow up for #87. Modified the second operand so that if
commentis not present it won't show a php error.Comment #89
wim leersThat works! 👍😄
Comment #90
wim leersRerolled on top of #3204212-52: Convert remaining widget and formatter type migrations to MigrateField plugins , due to conflict introduced by #3281427: Update Block and Theme setting migrations to not use Bartik and Seven, as well as on top of #3202462-20: [PP-1] Provide option for contrib modules to map their D6 / D7 field formatter and widget plugin IDs to the equivalent D9 plugin ID.
Straight rebase, so no interdiff.
Comment #91
wim leersRerolled on top of #3204212-58: Convert remaining widget and formatter type migrations to MigrateField plugins as well as on top of #3202462-20: [PP-1] Provide option for contrib modules to map their D6 / D7 field formatter and widget plugin IDs to the equivalent D9 plugin ID.
Comment #92
wim leersThere was a
*.orighunk in there, left over from previous patch iterations, that shouldn't have been there.