Score:0

การใช้การโยกย้าย (ด้วย) เพื่ออัปเดตโหนดที่มีอยู่แล้วใน Drupal

ธง cn

ฉันกำลังดำเนินการพอร์ตฐานข้อมูลที่ไม่ใช่ Drupal ไปยัง Drupal 9 ฐานข้อมูลดั้งเดิมประกอบด้วยตารางหนังสือ (พร้อมข้อมูลปกติ) และตารางแยกต่างหาก (อย่าถามฉันว่าทำไม) สำหรับหนังสือท่องเที่ยว เดิมคือระเบียน 10K และย้ายจากไฟล์ หนังสือ.csv เพื่อ Drupal หลัง (หนังสือท่องเที่ยว.csv) เป็นเพียง 200 บันทึก

สิ่งที่น่าสนใจ (น่าคิด!) คือหนังสือท่องเที่ยวส่วนใหญ่อยู่ในตารางหนังสือด้วย โดยมีช่องใหม่บางส่วนในตารางหนังสือท่องเที่ยว โดยเฉพาะอย่างยิ่งประเทศและจำนวนหน้า (อีกแล้ว!) ใน Drupal เรามีอนุกรมวิธานสำหรับ type_of_book กับสิ่งที่ชอบ ความโรแมนติก, การผจญภัย, เรื่องจริง, อาชญากรรม, บทกวี ฯลฯ.ตลอดจน หนังสือท่องเที่ยว.

หนังสือจาก หนังสือ.csv อยู่ใน Drupal แล้ว โดยมีโหนดใหม่และข้อกำหนดอนุกรมวิธานที่ถูกต้องที่ใช้กับฟิลด์ field_book_type ซึ่งแน่นอนว่าเป็นฟิลด์ที่มีหลายค่า

ตอนนี้ฉันต้องการย้าย หนังสือท่องเที่ยว.csv ใน Drupal แต่:

  • หากมีหนังสืออยู่แล้ว (ค้นหาด้วยชื่อเรื่อง เนื่องจาก ID ในตารางต้นฉบับแตกต่างกัน!) ให้อัปเดตโหนดใน Drupal โดยเพิ่มคำอนุกรมวิธาน หนังสือท่องเที่ยว
  • หากไม่มีหนังสือใน Drupal ให้สร้างหนังสือนั้นและตั้งค่าคำศัพท์อนุกรมวิธาน หนังสือท่องเที่ยว

จนถึงตอนนี้ ฉันสามารถทำได้ผ่านปลั๊กอินปลายทางที่กำหนดเอง ไม่ใช่แค่ด้วยการกำหนดค่าการย้ายข้อมูล YAML นี่คือสิ่งที่ฉันหวังว่าจะใช้:

ใช้: d66124cf-232b-4080-911c-1d26aefd0246
รหัสภาษา: th
สถานะ: จริง
การพึ่งพา: { }
รหัส: quote_fornitore_voucher_csv_import
คลาส: null
field_plugin_method: null
cck_plugin_method: null
การโยกย้าย_tags: null
การโยกย้าย_group: หนังสือ
ป้ายกำกับ: 'นำเข้าหนังสือท่องเที่ยว'  
แหล่งที่มา:
  ปลั๊กอิน: csv
  เส้นทาง: /Users/walter/travel_books.csv
  ตัวคั่น: ','
  สิ่งที่แนบมา: '"'
  header_offset: 0
  รหัส:
    - รหัส
  เขตข้อมูล:
    -
      ชื่อ: ID
      ป้ายกำกับ: 'รหัสเฉพาะ'
    -
      ชื่อ: book_title
    -
      ชื่อ: ประเทศ
    -
      ชื่อ: หน้า
    -
      ชื่อเรื่องย่อ
.....
  ค่าคงที่:
    travel_book: 'หนังสือท่องเที่ยว'
กระบวนการ:
  พิมพ์:
    ปลั๊กอิน: default_value
    default_value: หนังสือ
  field_pages: หน้า
  field_country: ประเทศ
  ชื่อเรื่อง: book_title
  field_book_type:
    ปลั๊กอิน: entity_lookup
    ประเภทเอนทิตี: taxonomy_term
    กำ: book_type
    bundle_key: วิดีโอ
    ที่มา: Constants/travel_book
  นิด:
    ปลั๊กอิน: entity_generate
    entity_type: โหนด
    กำ: หนังสือ
    bundle_key: พิมพ์
    value_key: ชื่อเรื่อง
    ที่มา: book_title
    access_check: 0
ปลายทาง:
  ปลั๊กอิน: 'เอนทิตี: โหนด' 
  overwrite_properties:
    - field_pages
    - field_country 
การโยกย้าย_การพึ่งพา: null

ฉันมีปัญหาสองประการกับการย้ายข้อมูลนี้:

  1. ถึงแม้ว่า เอนทิตี_สร้าง พบโหนดที่มีอยู่แล้วที่ถูกต้องสำหรับหนังสือปัจจุบัน Migration Engine ยังคงพยายามสร้างโหนดใหม่ด้วย NID เดียวกัน และแน่นอนว่าล้มเหลวด้วยข้อผิดพลาด SQL สีแดงขนาดใหญ่
23000]: การละเมิดข้อจำกัดด้านความสมบูรณ์: 1062 รายการซ้ำ '2662' สำหรับคีย์ 'หลัก': INSERT INTO "node" ("nid", "vid", "type", "uuid", "langcode") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4); อาร์เรย์
  1. ฉันเอาชนะสิ่งนี้ได้ เพียงแต่ไม่สามารถเพิ่มคำอนุกรมวิธานที่ถูกต้องลงในรายการของ Book ที่มีอยู่ได้ field_book_type.

ฉันติดตามปัญหาด้วย 1 เพื่อให้เอนทิตีมี บังคับใช้เป็นใหม่ ตั้งเป็น True หรืออย่างน้อยนั่นคือสิ่งที่ฉันได้พบ ฉันได้เขียนปลั๊กอินปลายทางที่สามารถบังคับเอนทิตีที่สร้างขึ้นใหม่โดยใช้การกำหนดค่าใหม่ตามการกำหนดค่าใหม่ การบังคับใช้ IsNew = FALSE และดูเหมือนว่าจะได้ผลตามที่คาดไว้ หนังสือท่องเที่ยวที่ไม่พบใน Books ใน nDrupal จะถูกสร้างขึ้น ในขณะที่หนังสือที่มีอยู่แล้วจะได้รับการอัปเดตพร้อมฟิลด์ หน้า และ ประเทศ ปรับปรุง

ฉันคิดว่านี่คือรหัสที่เกี่ยวข้อง

EntityBase ระดับนามธรรมใช้ EntityInterface {
...
  ฟังก์ชั่นสาธารณะ isNew () {
    ส่งคืน !empty($this->enforceIsNew) || !$this->id();
  }
...

แม้ว่าจะมี ID ซึ่งถูกตั้งค่าโดย นิดนึง กระบวนการ ตั้งค่าการบังคับใช้ IsNew เป็น จริง ดังนั้น isNew() จึงคืนค่า True

<?php

เนมสเปซ Drupal\migrate_books\Plugin\migrate\destination;


ใช้ Drupal\Core\Entity\Entity;
ใช้ Drupal\Core\Entity\EntityInterface;
ใช้ Drupal\migrate\Plugin\migrate\destination\EntityContentBase
ใช้ Drupal\migrate\Plugin\MigrationInterface
ใช้ Drupal\migrate\Row;
ใช้ Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * @MigrateDestination(
 * id = "update_node"
 * )
 */
คลาส UpdateNodeDestination ขยาย EntityContentBase {

  /** @var สตริง $entityType */
  $entityType แบบคงที่สาธารณะ = 'โหนด';
 
  ฟังก์ชันที่ได้รับการป้องกัน updateEntity (EntityInterface $entity, แถว $row) {
    $entity = parent::updateEntity($entity, $row);
    //ตรวจสอบพารามิเตอร์..
    if(!empty($this->configuration['prefer_update']) && $this->configuration['prefer_update']){
      // บังคับให้ไม่บังคับใช้ใหม่ สิ่งนี้จะหลีกเลี่ยงการแทรกสองโหนดที่มีอยู่แล้ว (ซึ่งจะส่งผลให้
      // ในการละเมิดความสมบูรณ์จาก MySQL
      $entity->enforceIsNew(เท็จ);
    }
    ส่งคืน $entity;

  }

}

และ YAMLS เปลี่ยนไปด้วยปลั๊กอินและพารามิเตอร์ใหม่ของฉัน ปรับปรุง

ปลายทาง: 
  ปลั๊กอิน: update_node
  prefer_update: จริง
  overwrite_properties:
    - field_pages
    - field_country

แต่สำหรับฉันแล้วดูเหมือนว่ามันควรจะง่ายกว่านั้น เห็นได้ชัดว่าฉันขาดอะไรไป ฉันแน่ใจว่านี่เป็นกรณีการใช้งานที่ค่อนข้างมาตรฐาน ดังนั้นจึงสามารถ/ควรทำได้ใน YAML ทั้งหมด

ประการที่สอง ฉันยังไม่สามารถเพิ่มสิ่งที่ถูกต้องได้ book_type ไปยังรายการแท็กที่มีอยู่ ถ้าฉันเพิ่ม field_book_type ถึง overwrite_propertiesแน่นอนว่ามันถูกเขียนทับและเราสูญเสียเงื่อนไขก่อนหน้านี้ทั้งหมด

ฉันดูเหมือนจะไม่มีวิธีอัปเดตโดยการเพิ่มค่าลงในฟิลด์ที่มีหลายค่า

ความช่วยเหลือใด ๆ ? ขอบคุณ ว

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา