Hi there --
I've been migrating a big, homegrown system over to D7. (I asked about another aspect of this earlier this week, #1536722: "Could not save to map table" for every item.) I'm almost there, but I just need to get files attached to the new nodes I've created. My file migration works fine; my node migration works fine, except that it's not getting its file fields filled. The files definitely exist in the files_managed table, and the migrate_map table exists for the file migration, so I'd expect that the node migration would be able to use those facts to grab the right fids and populate nodes' fields with them... no go. I must be doing something wrong in the code...? Perhaps it's something to do with the fact that I don't have a distinct id for files in the old system, so I was focred to use their filenames as sourceid1?
Anyway, thank you (again!) for any help you can give.
Ben
class ChFileMigration extends Migration {
public function __construct() {
parent::__construct(MigrateGroup::getInstance('clearinghouse'));
$this->map = new MigrateSQLMap($this->machineName,
array(
'art_binary' => array('type' => 'varchar',
'length' => 255,
'description' => 'Source record ID',
)
),
MigrateDestinationFile::getKeySchema()
);
$query = Database::getConnection('default', 'phi_migrate')
->select('article', 'a')
->distinct()
->fields('a', array('art_binary'))
->condition('art_binary', '', '!=')
->condition('art_binary', ' ', '!=');
$query->addField('a', 'art_binary', 'source_uri');
// Source
$this->source = new MigrateSourceSQL($query, array(), NULL, array('map_joinable' => FALSE));
// Destination
$this->destination = new MigrateDestinationFile(array('preserve_files' => TRUE));
// Mappings
$this->addFieldMapping('uri', 'source_uri');
}
public function prepareRow($row) {
$row->source_uri = file_default_scheme() . '://' . 'clearinghouse/' . $row->art_binary;
return TRUE;
}
}
class ClearinghouseMigration extends Migration {
public function __construct() {
parent::__construct(MigrateGroup::getInstance('clearinghouse'));
// Make sure the 2 term migrations happen first.
$this->dependencies = array('ChCat', 'ChTag', 'ChFile');
$this->map = new MigrateSQLMap($this->machineName,
array(
'res_id' => array('type' => 'int',
'length' => 10,
'unsigned' => TRUE,
'not null' => TRUE,
'description' => 'Source record ID',
)
),
MigrateDestinationNode::getKeySchema()
);
$query = Database::getConnection('default', 'phi_migrate')
->select('article', 'a')
->fields('a', array('res_id', 'art_author_fname', 'art_pubmonth', 'art_pubyear', 'art_date', 'art_volume', 'art_publisher', 'art_pub', 'art_http', 'art_binary', 'art_fulltext', 'art_order_details', 'art_entrydate', 'art_hardcopy', 'art_softcopy'));
// Resource table.
$query->join('resource', 'r', 'a.res_id=r.res_id');
$query->fields('r', array('res_name', 'res_abstract'));
$source_fields = array('tags', 'categories', 'res_id');
// Source
$this->source = new MigrateSourceSQL($query, $source_fields, NULL, array('map_joinable' => FALSE));
// Destination
$this->destination = new MigrateDestinationNode('articles_commentaries');
// Mappings
$this->addFieldMapping('title', 'res_name');
$this->addFieldMapping('body', 'res_abstract');
$this->addFieldMapping('field_author', 'art_author_fname');
$this->addFieldMapping('field_volume', 'art_volume');
$this->addFieldMapping('field_publisher', 'art_publisher');
$this->addFieldMapping('field_pub', 'art_pub');
$this->addFieldMapping('field_url', 'art_http');
$this->addFieldMapping('field_full_text_of_article', 'art_fulltext');
$this->addFieldMapping('field_ordering_info', 'art_order_details');
$this->addFieldMapping('field_old_ch_tags', 'tags');
$this->addFieldMapping('field_old_ch_cats', 'categories');
$this->addFieldMapping('field_file', 'art_binary')
->sourceMigration('ChFile');
} // end of constructor.
public function prepareRow($row) {
// Tags
$tag_query = Database::getConnection('default', 'phi_migrate')
->select('resource_tag', 'rt')
->condition('res_id', $row->res_id);
$tag_query->join('tag', 't', 'rt.tag_id=t.tag_id');
$tag_result = $tag_query->fields('t', array('tag_name'))
->condition('t.res_type_id', 0)
->execute();
foreach($tag_result as $line) {
$row->tags[] = $line->tag_name;
}
// Categories
$category_query = Database::getConnection('default', 'phi_migrate')
->select('category', 'c')
->fields('c', array('cat_name'));
$category_query->join('resource_category', 'rc', 'c.cat_id=rc.cat_id');
$category_query->condition('rc.res_id', $row->res_id);
$category_result = $category_query->execute();
foreach($category_result as $line) {
$row->categories[] = $line->cat_name;
}
return TRUE;
}
}
Comments
Comment #1
mikeryanTry
You need to tell the migration to interpret the incoming value as a fid rather than a URI.
Comment #2
bdimaggioAha! Did not understand that relationships between new entities and existing ones are created by the existing ones' values, rather than IDs. The migration went off without a hitch! Thanks again.
Comment #3
mikeryanComment #5
cameron prince commentedThe example code in the solution should now be as follows for 7.x-2.4:
Comment #6
peteruithoven commentedAnd with 2.4 (and the new argument system) it would be the following, right?
Comment #7
bdone commented@peteruithoven: yes. you're using the right syntax, but your sourceMigration should chain onto the field, vs. the file_class.