I have three migration classes. The first imports users and I've set the mapping as below with sortref and id part of the key.
$this->map = new MigrateSQLMap(
$this->machineName,
array(
'sortref' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
'id' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
),
MigrateDestinationUser::getKeySchema()
);
I then have a second class that has this mapping
$this->map = new MigrateSQLMap(
$this->machineName,
array(
'sortref' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
),
MigrateDestinationNode::getKeySchema()
) ;
with the following mappings:
$this->addFieldMapping('uid', 'sortref')
->sourceMigration('UserImport');
$this->addFieldMapping('title', 'id')
->sourceMigration(array('VenueImport'));
$this->addFieldMapping('field_venue', 'id')
->sourceMigration(array('VenueImport'));
The third class has
$this->map = new MigrateSQLMap(
$this->machineName,
array(
'id' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
),
MigrateDestinationNode::getKeySchema()
);
with
$this->addFieldMapping('uid', 'id')
->sourceMigration('UserImport');
In all three classes im bringing in the fields from the SQL db (there's only one table)
$query = Database::getConnection('default', 'for_migration')
->select('data', 'd')
->fields('d', array('id', 'sortref'.....
But the mappings aren't getting picked up. Some work (id->uid) when I remove the multipart key and just have id in the first class.
Could someone explain what I'm doing wrong and what's the correct way of handling mulitpart keys. Should I be specifying which part of the key to use in the field mapping? Any help greatly appreciated
Comments
Comment #1
mikeryanJust to make sure I understand your source schema - each user is uniquely identified by a combination of sortref and id, each node in your second migration is uniquely identified by sortref, and each node in your third migration is uniquely identified by id? If so, then for sourceMigration() to work in referencing users you need to have both sortref and id as part of the key. Since addFieldMapping() only takes one source field, you need to paste it together in prepareRow():
Thus, when handleSourceMigration() is called, it is passed both parts of the key and can properly lookup the user in the map table.
Comment #2
Anonymous (not verified) commentedComment #3
fuerst commentedJust for clarification - I understand the example as following: Each user is identified by a multi column (aka: field) key constructed from sortref and id. In SQL syntax it would look like this:
INDEX user (sortref, id).handleSourceMigration()allows 3 different key variants:In this exampe we have one multi-field key so the code must look like this:
Only difference to #1 is the $row->constructed_key just got wrapped into another array. That way it works for me when using multi column keys.
Comment #4
benjifisher@bjalford, @mikeryan, @fuerst:
Thanks for asking and answering the question! I was about to create a new issue, but since you already did, I do not have to wait for an answer.
I added a section to the documentation page on Field mappings: https://drupal.org/node/1133448#sourcemigration .
Comment #5
gaxze commented@fuerst I have been pulling my hair out as to why I was unable to get entity reference working. that second array for the constructed key was my issue.