D8迁移到附加到帐户的field_ip地址

时间:2018-06-13 21:24:08

标签: migration drupal-8

我正在研究D8中的一个迁移脚本,该脚本来自MySQL数据库,并将填充此模块创建的D8中的表...

https://github.com/bjaxelsen/field_ipaddress 这个模块是这个的D8端口...... https://www.drupal.org/project/field_ipaddress

无论如何我安装了模块并将字段添加到帐户中,其值不受限制。

一般用户迁移已经完成并且正常工作。它会将用户名,电子邮件和状态迁移到Drupal,这一切都很好。

第二次迁移是将用户IP地址列表移动到D8。我的数据集看起来像这样......

user_id  slstatus   status_id   ipFrom   ipTo       modifyDateUnix
50374    1          0           1.1.1.1  1.1.1.1    1505415351
25108    0          1           4.4.4.0  4.4.4.255  1479243329

真实代码运行mysql中的INET_ATON函数返回整数,但上面显示意图。

在准备行功能中,我还将IP地址转换为十六进制值,这是db表存储所需的。

slstatus与用户的活动状态有关,而status_id与ip记录的状态有关。这些用于确定名为deleted的新变量。我还创建了一个名为idx的变量,它是一个......很好的索引。所有这些新字段都会添加回该行。

我的YAML看起来像这样,是我头痛的开始......

id: UserIpsMigrate
migration_group: 'UMG'
label: 'User IP Migration'
source:
  plugin: UserIpsMigrate
process:
  'field_ip_address/bundle': 'user'
  'field_ip_address/deleted': deleted
  'field_ip_address/entity_id':
    plugin: migration_lookup
    migration: UserMigrate
    source: user_id
  'field_ip_address/revision_id':
    plugin: migration_lookup
    migration: UserMigrate
    source: user_id
  'field_ip_address/langcode': 'en'
  'field_ip_address/delta': idx
  'field_ip_address/field_ip_address_ip_ipv6': 0
  'field_ip_address/field_ip_address_ip_from': ipFrom
  'field_ip_address/field_ip_address_ip_to': ipTo
destination:
  plugin: entity:user
  default_bundle: migration
  migration_dependencies:
    required:
      - user_migrate

我得到的错误表明此迁移正在尝试创建一个用户...这将使这些数据失败,所以我确定我需要使用不同的目标插件,但我不知道...... 1)我应该使用哪个目标插件 2)如果我去了轨道"我的yaml

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。

首先,我将yaml文件更改为如下格式。

id: UserIpsMigrate
migration_group: HEUMG
label: 'User IP Migration'
source:
  plugin: tUserIpsMigrate
process:
  bundle:
    plugin: default_value
    default_value: user
  deleted: deleted
  entity_id:
    plugin: migration_lookup
    migration: UserMigrate
    source: user_id
  revision_id:
    plugin: migration_lookup
    migration: UserMigrate
    source: user_id
  langcode:
    plugin: default_value
    default_value: en
  delta: delta
  field_ip_address_ipv6:
    plugin: default_value
    default_value: 0
  field_ip_address_ip_from: ipFrom
  field_ip_address_ip_to: ipTo
destination:
  plugin: field_ip_address
  migration_dependencies:
    required:
      - user_migrate

我还发现,GetIds()函数对于确定从源到目标的映射非常重要,并且在制作迁移映射表时由迁移系统使用。

扩展sqlBase类,我有一个查询来提取迁移所需的数据,它将使用来自不同表用户和ipaddress的2个键。所以我的源getIds()函数看起来像这样……

 /**
  * {@inheritdoc}
  */
 public function getIds() {
   return [
     'user_id' => [
       'type'  => 'integer',
       'alias' => 'slc',
     ],
     'siteLicense_id' => [
       'type' => 'integer',
       'unsigned' => FALSE,
     ],
   ];
 }

...和我的目的地getIds以此终止...

  /**
   * {@inheritdoc}
   */
  public function getIds() {
    return [
      'entity_id' => [
        'type' => 'integer',
        'unsigned' => FALSE,
      ],
      'deleted' => [
        'type' => 'integer',
        'size' => 'tiny',
      ],
      'delta' => [
        'type' => 'integer',
        'unsigned' => FALSE,
      ],
      'langcode' => [
        'type' => 'string',
        'max_length' => 32,
        'is_ascii' => TRUE,
      ],
    ];
  }

使用上面的getIds()定义后,运行drush命令(例如“ drush migration:status”)后,将创建一个新表。

表“ migrate_map _” +您的迁移ID或在我的情况下为migration_map_useripsmigrate是使用source_id_hash,sourceid1,sourceid2,destid1,destid2,destid3,desstid4,source_row_status,rollback_status,last_imported和哈希值的字段创建的。源字段和目标字段映射到上面定义的getId,这是迁移系统如何跟踪此特定迁移中所有已运行的迁移的方式。其他迁移将有自己的表。

对于目标插件本身,我必须基于扩展DestinationBase类来制作自己的目标插件。

扩展DestinationBase要求您定义3个函数的内部,即import,getIds和field。我上面介绍的GetIds和字段就像在SQL源插件中定义字段一样。导入是您的目标插件将源数据保存到目标的方式。就我而言,我使用了这样的插入查询...

  /**
   * {@inheritdoc}
   */
  public function import(Row $row, array $old_destination_id_values = []) {
    $bundle                   = $row->getDestinationProperty('bundle');
    $deleted                  = $row->getDestinationProperty('deleted');
    $entity_id                = $row->getDestinationProperty('entity_id');
    $revision_id              = $row->getDestinationProperty('revision_id');
    $langcode                 = $row->getDestinationProperty('langcode');
    $delta                    = $row->getDestinationProperty('delta');
    $field_ip_address_ipv6    = $row->getDestinationProperty('field_ip_address_ipv6');
    $field_ip_address_ip_from = $row->getDestinationProperty('field_ip_address_ip_from');
    $field_ip_address_ip_to   = $row->getDestinationProperty('field_ip_address_ip_to');

    $result = $this->con->insert('user__field_ip_address')
  ->fields([
        'bundle'                   => $bundle,
        'deleted'                  => $deleted,
        'entity_id'                => $entity_id,
        'revision_id'              => $revision_id,
        'langcode'                 => $langcode,
        'delta'                    => $delta,
        'field_ip_address_ipv6'    => $field_ip_address_ipv6,
        'field_ip_address_ip_from' => $field_ip_address_ip_from,
        'field_ip_address_ip_to'   => $field_ip_address_ip_to,
      ])
      ->execute();

    return [
      'entity_id' => $entity_id,
      'deleted'   => $deleted,
      'delta'     => $delta,
      'langcode'  => $langcode,
    ];

  }

返回值应与目标getIds()函数中定义的字段相同,并且顺序相同。

这可能不是编写目标插件的最理想方法,但是它确实有效。