我需要从数据库中加载的源中将术语列表导入到我的分类法中。问题是,我已经在我的网站上准备好了这个分类法(通过迁移加载),其中包含了在其他内容中引用的术语,所以我必须保留现有术语并更新它们或创建新术语。
为了链接我的分类法源和现有的分类法,我为每个术语都有一个唯一的代码,所以我在词汇表中添加了一个代码字段,并为每个现有术语填充它。
我目前可以使用当前的迁移类创建和更新术语,但如果我在网站上的术语名称和源中的术语名称不同,即使代码相同,导入也会创建一个新术语,而不是更新其名称。
这里是我的迁移类:
class TotoMigration extends Migration {
private $list_term = array();
public function __construct($arguments) {
parent::__construct();
$this->softDependencies = array('TotoParent');
// get data from the custom table containing the new terms to create or update
$query = db_select('toto', 'f')
->fields('f', array(
'CODE', // code
'LIBLONG', // name
'PARENT', // parent
)
);
$this->source = new MigrateSourceSQL($query);
$this->destination = new MigrateDestinationTerm('toto_tax');
$this->map = new MigrateSQLMap($this->machineName,
array(
'CODE' => array('type' => 'varchar',
'length' => 5,
'not null' => TRUE,
'description' => 'Code',
)
),
MigrateDestinationTerm::getKeySchema()
);
$this->addFieldMapping('name', 'LIBLONG');
$this->addFieldMapping('field_code', 'CODE');
$this->addFieldMapping('parent', 'PARENT')
->arguments(array('source_type' => 'tid'))
->sourceMigration('TotoParent');
// create a list of existing toto terms with code => tid
$list_term = db_query("select fc.field_code_value, ttd.tid
from taxonomy_term_data ttd
left join taxonomy_term_hierarchy tth on tth.tid=ttd.tid
left join field_data_field_code fc on fc.entity_id = ttd.tid
where ttd.vid=10
and tth.parent!=0;")->fetchAllKeyed();
}
public function prepareRow($row) {
// Always include this fragment at the beginning of every prepareRow()
// implementation, so parent classes can ignore rows.
if (parent::prepareRow($row) === FALSE) {
return FALSE;
}
// if the destination is not mapped in migrate we tell him where to go
if (!isset($row->migrate_map_destid1) && isset($list_term[$row->CODE])) {
$row->migrate_map_destid1 = $list_term[$row->CODE];
}
}
}
然后我用drush(和--update选项)加载导入。我一定是错过了什么,如果有人知道的话,欢迎。
经过多次尝试,问题在于模块Migrate不支持在同一个迁移类中创建内容和更新内容(我甚至读到它有时会声称更新内容,但什么都不做)。
因此,解决方案非常简单,创建2个类:
- 一个用于创建内容
- 一个用于更新内容
您的创建类将是相同的。
您的Updating类需要将systemeOfRecord设置为DESTINATION:
$this->systemOfRecord = Migration::DESTINATION;
因此,它知道只更新而不重新创建内容,它将保持未映射的当前字段,并更新不属于MigrateSQLMap:的映射字段
$this->map = new MigrateSQLMap($this->machineName,array(...));
棘手的部分是找到内容的相应nid/tid,以便将其映射到导入的数据,然后映射到用于更新或创建内容的单独数据。