migration - D8 迁移到附加到帐户的 field_ip 地址
问题描述
我正在处理 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 记录的状态有关。这些用于确定称为已删除的新变量。我还创建了一个名为 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 “脱轨”
解决方案
我找到了解决方案。
首先,我将 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 类,我有一个查询来提取迁移所需的数据,它将使用来自不同表用户和 ipaddresses 的 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 migrate:status”。
表“migrate_map_”+您的迁移 ID 或在我的情况下为 migrate_map_useripsmigrate 是使用 source_id_hash、sourceid1、sourceid2、destid1、destid2、destid3、destid4、source_row_status、rollback_status、last_imported 和 hash 字段创建的。源和目标字段映射到上面定义的 getId,这就是迁移系统如何跟踪从这个特定迁移运行的所有迁移。其他迁移将有自己的表。
至于目标插件本身,我必须基于扩展 DestinationBase 类制作自己的目标插件。
扩展 DestinationBase 需要您定义 3 个函数的内部结构,即 import、getIds 和 fields。我在上面介绍的 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() 函数中定义的字段相同,并且顺序相同。
这可能不是编写目标插件的最理想方法,但它确实有效。
推荐阅读
- octave - 在 Octave 中安装软件包时“无法解析主机名”
- angular - ViewChild 的子项作为组件引用
- visual-studio-2017 - 如何将 SSAS 多维数据集从一个项目复制到另一个项目?
- regex - 没有零的正则表达式日期
- c++ - c++代码的安全性与有符号和无符号之间的隐式转换
- mysql - 访问筛选器不适用于 ADODB.Recordset 连接错误(无法初始化数据提供程序
- webpack - 有没有办法在事先不知道 JS 块的情况下动态加载它们?
- composer-php - Composer:文件的校验和验证失败
- oracle - 图像显示在 oracle apex 中崩溃
- python - 在字典中创建帕斯卡三角形