Drupal - 从表中导入迁移模块的分类法并创建/更新现有术语

时间:2015-12-21 17:40:38

标签: drupal drupal-7 migrate drupal-taxonomy

我需要从我在数据库中加载的源中将术语列表导入到我的分类中。 问题是我已经在我的网站上加载了这个分类(在没有迁移的情况下加载),其中的条款在其他内容中被引用使用,因此我必须保留现有术语并更新它们或创建新术语。

要链接我的分类源和现有分类法,我为每个术语都有一个唯一的代码,所以我在我的词汇表中添加了一个代码字段,并为每个现有术语填充它。

我目前能够使用当前的Migration类创建和更新术语,但如果我在网站上的术语名称和源代码中的术语名称不同,则导入将创建一个新术语而不是更新它的名字即使代码是相同的。

这是我的迁移类:

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选项)。 我必须遗漏一些东西,如果有人知道它会受到欢迎。

1 个答案:

答案 0 :(得分:0)

经过多次尝试,问题在于模块Migrate不支持在同一个迁移类中创建内容和更新内容(我甚至读过它会声称更新内容并且什么也不做)。

所以解决方案很简单,创建2个类:

  • 一个用于创建内容
  • 一个用于更新内容

您的Creating类将是相同的。

您的更新课程需要将systemeOfRecord设置为DESTINATION:

$this->systemOfRecord = Migration::DESTINATION;

因此它知道只更新而不重新创建内容,它将保持当前字段不被映射并更新映射的不属于MigrateSQLMap的字段:

$this->map = new MigrateSQLMap($this->machineName,array(...));

棘手的部分是查找内容的相应nid / tid,以便将其映射到导入的数据,然后分隔用于更新或创建内容的数据。