Issue: There appears to be a requirement that the $item_ID_xpath argument passed in when creating MigrateSourceXML needs to exist and to be an integer. I have XML that does not consistently meet both of those requirements that I need to import. I have one field that doesn't always have a value associated with it and another that sometimes has an "a" or "b" at the end of it (e.g. 000002a).
Proposed Solution: Write one or more override classes for MigrateSourceXML and others that allows the $item_ID_xpath to be a non-integer.
Is this possible, or is the requirement of an integer part of some structural need of Migrate? If it is possible, what classes would I need to override?
I thought I had this figured out and I am on a deadline for getting this figured out, so any help is greatly appreciated! Also, Migrate kicks ass!
Comments
Comment #1
mikeryanWhat type did you use for your source ID in your MigrateSQLMap constructor? If your source IDs are strings, it should be a varchar, not an integer.
The source ID must exist - the point of it is to be a unique key to keep track of how your source data maps to the destination.
Comment #2
pyrello commented@mikeryan - thank you for your prompt response and attention to this.
I'm a little confused by your response. What is the connection between the source id and the $item_ID_xpath. Are they somehow connnected?
Here is the code relating to my source id:
Currently, my source id is not set to anything on the xml, because there is no field that is completely unique. Previously, I had been trying generate a source id in the
prepareRow()function, but that was causing problems and when I updated migrate to the most recent version and removed that code, it just seemed to work, without setting source id to anything. That worked for importing 800+ records out of 30k. But now I am stuck again.In case it is helpful, here is the complete contents of my document.inc file:
Comment #3
pyrello commentedHere is the error I get with the above code that sets the value of
$item_ID_xpathto a field that does not always contain a value.Comment #4
pyrello commentedAfter changing
$item_ID_xpathback tofilename- which always has a value, but is a non-integer string, I am getting the following error message:This time through it has managed to import about 800+ items again. So I am pretty confused about what exactly the issue is here.
Comment #5
mikeryanFirst off, your code currently shows:
But the error message "Incorrect integer value: 'marion_volume1thru5_page_001' for column 'sourceid1' at row 1: INSERT INTO {migrate_map_document}..." suggests that when you first created this migration, your map had int rather than varchar, correct? You're running into #1175304: warn if map/message tables are out of sync with key schema - you need to rollback the migration, then manually delete the migrate_map_document and migrate_message_document tables. They will then get recreated with the proper sourceid1 (varchar) definition.
The next problem is the 'sourceid' in that call - this key needs to be the name of the field in your source field that represents the unique key, the one pointed to by $item_ID_xpath - i.e., 'filename'. The idea is that Migrate uses the $item_ID_xpath to find the key value for each item migrated, which is the value that will be stored in the sourceid1 columns in the map and message tables, which are created according to the field schema in the MigrateSQLMap call.
Comment #6
pyrello commented@mikeryan, thank you for the prompt response!
This all makes a lot of sense and explains a lot of the errors I have been seeing. The only issue I see with the above comment is that there is no completely unique field. From XML file to XML file, the filename may be duplicated many times over. It is only unique per XML file. Is that going to be a problem for using it as my source id?
Comment #7
mikeryanYes, it is a problem. It is essential that there be a unique identifier for each migrated object. Unfortunately, there's no place to insert something that would manufacture a unique ID from, say, the XML filename and the filename field - prepareRow() gets called too late for that. You'll have to extend MigrateSourceXML and override getNextRow() to do this - I think if at the end of that you did something like
that may work. You may have to hash it or do something else clever to make sure it doesn't go over 255 characters.
Comment #8
pyrello commented@mikeryan, I have followed the instructions provided in #5. Now when I attempt to access the migrate UI, I get the following error:
I don't immediately understand what this error is about.
Comment #9
mikeryanvarchars need a size - add 'size' => 255,
Comment #10
pyrello commentedMade that change:
... getting a new error:
Also tried uninstalling and reinstalling. Looked to make sure that there weren't database tables that needed to be dropped.
Comment #11
mikeryanSorry, my bad, instead of 'size' use 'length'.
Comment #12
pyrello commentedThanks, that got me to the point where the migrate page loads again! I just got back from DrupalCon, so I am going to spend some time looking into this to see what other issues there are. Thanks for your help troubleshooting.
Comment #13
mikeryanComment #15
tinflute commentedWould timestemp type be supported as key for MigrateSourceXML ?
A timestamp is simple, reliable, & portable way to ensure uniqueness of keys.
Right now i'm just treating the values as varchar but epoch representation in the DB would make more sense.