我正在研究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
答案 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()函数中定义的字段相同,并且顺序相同。
这可能不是编写目标插件的最理想方法,但是它确实有效。