Problem/Motivation

User stories:

  1. As a site administrator upgrading from a Drupal 7 site running recipe-7.x-1.3 to a Drupal 8 site running recipe-8.x-2.x, I would like recipes on the old site to be migrated to the new site automatically, so that I don't have to spend time re-entering my recipe collection.

Proposed resolution

Write a migration path (not sure what is involved in this yet).

Remaining tasks

  1. Determine what needs to be done
  2. Link to relevant documentation
  3. Write migrations for ingredients and ingredient settings
  4. Allow ingredients to be associated with recipe nodes via recipe_ingredient
  5. Write migrations for recipe_cook_time, recipe_prep_time, recipe_yield_amount, recipe_yield_unit
  6. Write migrations for recipe_description, recipe_instructions, recipe_notes, recipe_source
  7. Review and feedback
  8. RTBC and feedback
  9. Commit
  10. Release

User interface changes

No changes to the D8 recipe module or ingredient sub-module UI. Hopefully no alterations to the Drupal 8 core Migrate UI.

API changes

No changes to the D8 recipe API.

Data model changes

No changes to the recipe data model in D8.

Useful resources

Comments

mparker17 created an issue. See original summary.

dcam’s picture

Yeah, it's on my to-do list, particularly since the migration paths are the primary thing holding back an 8.x-2.x release. I haven't worked on it yet because the 7.x-2.x data structure is not finalized, but I suppose there really isn't any reason I can't write the path for 7.x-1.x. I'll look into it sometime this weekend.

mparker17’s picture

I would like to help: my employer's website has a number of recipes on it, and I'd like them to migrate automatically when I upgrade the site to Drupal 8. I'll see if I can start a patch sometime later today.

dcam’s picture

Well, if you get to it before I do there is a 7.x-1.3 data file for creating tests already in the 8.x tests directory. I'm not sure if that will be reusable for 8.x migrations. It was originally made for testing 7.x-2.x upgrades.

dcam’s picture

StatusFileSize
new10.5 KB

Testing the 7.x-1.3 ingredient migration.

dcam’s picture

Status: Active » Needs review

It helps to set the status.

dcam’s picture

StatusFileSize
new12.22 KB

Added the ingredient settings migration, not including the ones that got changed to field settings. The test is failing locally even though the migration works in practice. I want to see what it does here.

Status: Needs review » Needs work

The last submitted patch, 7: 2907763-7-ingredient-settings.patch, failed testing. View results

dcam’s picture

Status: Needs work » Needs review
StatusFileSize
new12.37 KB

I thought I'd copied in the fixture path method. Apparently not.

dcam’s picture

StatusFileSize
new12.89 KB

Updated migration and test namespaces to match the Recipe source version.

dcam’s picture

StatusFileSize
new15.77 KB

Quitting for the night - just uploading what I got done. I added all of the recipe fields. It worked in manual testing. I didn't finish the automated tests before deciding to stop. Another migration to copy the remaining ingredient settings into the recipe field still has to be written, but I think that's the last thing.

mparker17’s picture

Assigned: Unassigned » mparker17
Issue summary: View changes

@dcam awesome, thanks! I'll test it now!

***

(I had also started on the Ingredient migration, but I forgot to assign the issue to myself before I started, so you beat me to a patch by about 4 minutes — although it looks like yours was more complete than mine).

***

I've updated the issue summary's remaining tasks with a preliminary list, and I've added some links that I found useful to the bottom.

mparker17’s picture

Issue summary: View changes

Testing on a machine running macOS 10.12.6, with Apache 2.2.31, PHP 7.0.15, and Oracle MySQL 5.6.35 with drupal-8.4.x at commit a5581d153d and recipe-8.x-2.x at commit d935683 with the patch in #11 applied, I can confirm that MigrateIngredientSettingsTest and MigrateIngredientTest both complete successfully; and that it can successfully migrate real-world ingredient data from my employer's (Brady's Meat & Deli) D7 website to D8 without duplicates on a fresh install of D8 and a migration through the UI.

Also, reviewing the code in the patch itself, everything looks great! Very clear.

Awesome! Thanks very much @dcam, this is great! Marking the "Remaining task" for migrating ingredient entities as done.

***

Leaving this assigned to me so I can try my hand at associating ingredients with recipe nodes, and some of the other field migrations.

mparker17’s picture

StatusFileSize
new17.64 KB
new2.22 KB

Really minor change... while creating test cases for recipe itself, I realized there was a \Drupal\Tests\ingredient\Kernel\Migrate\recipe713\MigrateRecipe713TestBase which was the base class for both MigrateIngredientSettingsTest and MigrateIngredientTest; so I've renamed it MigrateIngredient713TestBase.

Status: Needs review » Needs work

The last submitted patch, 14: 2907763-14-rename-ingredient-testbase.patch, failed testing. View results

dcam’s picture

That's fine. I think I named it that to match the version of the module that the data came from, but it doesn't really matter. It will reduce confusion.

dcam’s picture

If you still have your first patch you can upload it, if you have any interest in me reviewing it and telling you why I did things differently.

dcam’s picture

Your comment in #13 suggests that the recipe field migrations from #11 did not work for you. Did it not work?

mparker17’s picture

Status: Needs work » Needs review

Sorry for the delay in responding: when I migrated the real-world data, the ingredients were migrated into Ingredient entities, and the recipe nodes were migrated, but all recipe nodes had empty recipe_ingredient, recipe_cook_time, recipe_prep_time, recipe_yield_amount, recipe_yield_unit, recipe_description, recipe_instructions, recipe_notes, and recipe_source fields.

dcam’s picture

Huh. Weird. Maybe I forgot to include something in the patch. I was getting tired at that point. I'll check in a few minutes when I'm back on my laptop.

dcam’s picture

The recipe data migration files are in #11. Check to make sure you have these two files:
- migrations/recipe713_recipe.yml
- src/Plugin/migrate/source/recipe713/Recipe.php

If you don't, then maybe you accidentally downloaded the wrong patch. If you do, then I'm not sure what went wrong, but it would be a good idea to find out. Maybe you just needed to rebuild your cache before the upgrade. I had that happen once, but it was because I exported the base D8 database so that I could just import that after every test instead of going through the install process. It doesn't make sense that you would have been able to successfully import the ingredients, but not the recipe fields if you were experiencing the same issue.

When you go into the migration path confirmation form, you should see Ingredient and Recipe listed together under the destinations. If you know you have the files, but Recipe isn't listed there then something is wrong and the recipe data plugin isn't being detected.

mparker17’s picture

Assigned: mparker17 » Unassigned
StatusFileSize
new231.28 KB
new148.61 KB
new179.43 KB
new218.31 KB
new30.69 KB
new12.93 KB

I have to go shortly but I'm uploading my work thus far.

After adding a basic test and using the fixture in tests/fixtures/recipe713.php, I was getting errors that the tables from the node and system modules didn't exist, so I added them, copying data from the Drupal 7 hook_schema() definitions. This seemed to work except for creating the system table, which failed with a SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes. My understanding is that since my dev site uses utf8mb4, trying to set the filename column to VARCHAR(255) and then saying it was the primary key was is causing that.

***

RE: #21 — I'm pretty sure I was using the patch in #11.

I have tried again using the patch in this issue. I confirmed that my version of recipe has both of those files. I flushed all caches before the migrate process. I could see both recipe and ingredient listed in the table of "Available upgrade paths".

Running the migration, I again see that the recipes and ingredients imported, but editing a recipe shows that the relationship between that recipe and its ingredients were not imported. See attached screenshots.

The only thing worth noting is that, in both cases, the migration failed at the end with the following error: Error: Call to a member function getFileUri() on null in Drupal\image\Plugin\Field\FieldType\ImageItem->preSave() (line 317 of core/modules/image/src/Plugin/Field/FieldType/ImageItem.php). but I think this is unrelated, for a number of reasons:

  1. Database logs show (in chronological order):
    1. "Upgraded Ingredient configuration (processed 1 item…"
    2. "Upgraded Nodes (Recipe) (processed 25 items total)"
    3. "Upgraded Ingredients (processed 108 items total)"
  2. At the end, the migrate wizard reports the status "Completed 60 upgrade tasks successfully, 1 upgrade failed".
  3. My D7 Recipe content type has no image fields in it
  4. The D8 Recipe content type has no image fields in it — it is literally a fresh site install with the standard install profile

...my only thought is that maybe that failure prevents something else from running, but the database logs seem to suggest that all three recipe migrations happened.

Status: Needs review » Needs work

The last submitted patch, 22: 2907763-22-start-work-on-recipe-migration-tests.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dcam’s picture

Title: Migrate data from D7 to D8 » Migrate data from 7.x-1.3 to 8.x-2.x

RE: fixtures
I encountered the exact same error about the tables not being installed when writing the Ingredient module tests. D8 fixtures must have different requirements than ones made for D7. Since I already had core's D7 fixture (located in the migrate_drupal module) open to see what a newer fixture looked like, all I did was copy the create table commands for the system and variable tables from it into the ingredient fixture. It worked with no problem.

RE: non-migrated recipe data
Well, that's just disappointing. It looks like not only did your ingredient references not get migrated, nothing else did either. At the moment I don't have any idea what the problem is. I ran one test migration with the code in that patch last night. It contained two test recipes (I no longer have access to real-world data). Both had all their fields imported with no issue. I'll think about it, run the migration again, and see if the test has the same issue that you did.

I'm also inclined to think that the image issue was unrelated. The recipe imports run separately from the main node migration and their D7 fields. Maybe if the node migration was marked as being failed, that might cause it. The recipe data migration is dependent on it. Also, because it's separate it won't be listed as "Nodes (Recipe)" in the log. You want to look for the "Recipe data" migration log, which is the title given in the migration YAML file.

dcam’s picture

I had a thought. Have you checked your database to see if the field data was actually migrated? If the data got migrated then maybe it's just not showing up on the front end. I expect that the nodes are given the same ID numbers that they had in the D7 site, but what if they are being changed during the migration? The fields are being given the D7 nid. If the nid's are being changed for some reason then the nid in the recipe migration simply needs to be run through the migration processor plugin to map the old nid to the new one.

dcam’s picture

Status: Needs work » Needs review
StatusFileSize
new23.97 KB

The dependencies of the recipe migration and of the recipe nodes caused the number of tables that had to be installed by the test to balloon until I just got sick of it and said "Screw it, I'll just install core's fixture, wipe the node tables, and then install the recipe fixture after." So, that's what I did. This wasn't necessary in D7 and I'm hoping that there's a better way in D8, but I didn't get around to looking into recommended methods for creating fixtures and maybe not having to load quite so many tables. So this is what I have for the moment, which seems to be working.

dcam’s picture

StatusFileSize
new15.57 KB

There were a couple of other minor changes in that patch that I'd forgotten to include with git add: a migration constant that I'd added, but didn't need; an update to the test docblock; and changing the test method name to assertRecipeFields().

Here's an interdiff that includes those changes, if you're interested.

dcam’s picture

StatusFileSize
new54.61 KB

I recreated the fixtures using the D8 fixture-creating tool. The recipe713 fixture has to include more unrelated tables than I would like, but it does make the code simpler.

dcam’s picture

Category: Feature request » Task
Priority: Normal » Critical
Issue tags: +beta blocker
dcam’s picture

StatusFileSize
new55.48 KB

I wasted two nights trying to figure out what wrong with the ingredient field setting migration only to figure out that it was... nothing. Nothing was wrong. I had just failed to set the value that I expected in the D7 instance from which I was migrating.

dcam’s picture

StatusFileSize
new57.68 KB

Added the ingredient field display settings migration. This should complete the migration path from 7.x-1.3. Please check it out, @mparker17. We still need to figure out what was going wrong with the recipe data migration in your case.

Status: Needs review » Needs work

The last submitted patch, 31: 2907763-31-field-display-settings.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dcam’s picture

Status: Needs work » Needs review
mparker17’s picture

@dcam, will-do. Thanks again for your hard work on this! Sorry for not being very active/helpful during the week... I usually only get a chance to work on stuff for Brady's on my weekends.

dcam’s picture

Don't worry about it. Thanks for checking it.

mparker17’s picture

Hmm... it still did not migrate the data in my test database... but I'm starting to wonder if maybe the issue is my test database; not the migration. I'll see if I can figure out if/what is wrong with my test database.

dcam’s picture

Could you dump your node and recipe tables and upload them?

mparker17’s picture

Status: Needs review » Reviewed & tested by the community

I did some investigation, and I'm pretty sure that the problem is indeed my data.

Some recipes were migrated from Drupal 6 to Drupal 7, and then a bit later, the locale module was added and the default language was set to English. This has resulted in some recipe nodes and/or their revisions and/or their fields are marked as LANGUAGE_NONE, and others are marked as English.

When I normalize all the data related to recipes as either English or LANGUAGE_NONE, the recipe migration works perfectly with the patch from #31. Since the only reference to languages in the patch are in the fixtures, I assume this is an issue with Drupal core's migrate_drupal module — I guess this would count as some sort of (accidental) entity translation, so its probably #2073467: Migrate Drupal 7 Entity Translation settings to Drupal 8 or something related.

***

+1 to RTBC from me.

Thanks @dcam for all your hard work!

dcam’s picture

Status: Reviewed & tested by the community » Needs work

Thanks for reviewing it and for figuring out what was going on. Unfortunately, this is concerning to me and I think it's probably a major bug with the upgrade path. The D7 recipe data have no language other than what their nodes are. I think that the node's language needs to be inserted manually into the D8 fields in order keep problems like this from happening. I'm going to work on it a bit more and try to resolve the issue.

dcam’s picture

Status: Needs work » Needs review
StatusFileSize
new65.82 KB

This was a challenge to figure out, but fortunately I was able to follow along with what was done for multilingual nodes. The differences in how D8 handles translations versus how D7 handles translations are at the heart of the issue. In D7 all nodes get separate nid's and translations just reference the original. In D8, a piece of content and all of its translations are treated as a single node with one nid.

@mparker17, if you're still watching this issue and you still have access to unmigrated data could you try out this patch to see if it properly migrates your content?

mparker17’s picture

@dcam, I will when I have the chance; but that might not be until Saturday. I'll try to get to it earlier! Thanks again for your hard work!

dcam’s picture

Take your time. I just appreciate that you're willing to test it.

mparker17’s picture

Status: Needs review » Reviewed & tested by the community

@dcam, sorry for the long delay in getting around to testing this.

The patch in #40 works perfectly! All the ingredients migrated properly. Thanks again for all your hard work on this! This is RTBC from me!

dcam’s picture

Don't worry about it. Thank you for the review.

  • dcam committed bd644e0 on 8.x-2.x
    Issue #2907763 by dcam, mparker17: Migrate data from 7.x-1.3 to 8.x-2.x
    
dcam’s picture

Status: Reviewed & tested by the community » Fixed

Thanks again for the help, @mparker17.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.