Tôi đang trong quá trình chuyển cơ sở dữ liệu không phải Drupal sang Drupal 9.
Cơ sở dữ liệu ban đầu chứa, trong số những thứ khác, một bảng Sách (với thông tin thông thường) và một bảng riêng (đừng hỏi tôi tại sao) cho Sách Du lịch. Cái trước là 10 nghìn bản ghi và đã được di chuyển thành công từ một sách.csv
đến Drupal. cái sau (sách du lịch.csv
) chỉ là 200 bản ghi.
Điều thú vị (sic!) là hầu hết các Travel Books cũng nằm trong bảng Books, với một số trường mới trong bảng Travel Books, đáng chú ý là quốc gia và số trang (sic một lần nữa!).
Trong Drupal, chúng tôi có phân loại cho loại sách
với những thứ như lãng mạn
, cuộc phiêu lưu
, chuyện có thật
, tội phạm
, thơ
v.v.. cũng như sách du lịch
.
sách từ sách.csv
đã có trong Drupal, với các Nút mới và các thuật ngữ phân loại chính xác được áp dụng cho trường trường_book_type
tất nhiên, đó là một trường đa giá trị.
Bây giờ tôi muốn di cư sách du lịch.csv
trong Drupal nhưng:
- nếu một cuốn sách đã tồn tại (tra cứu theo tiêu đề, vì ID trong các bảng gốc khác nhau!), chỉ cần cập nhật nút trong Drupal, thêm thuật ngữ phân loại
sách du lịch
- nếu một cuốn sách không tồn tại trong Drupal, hãy tạo nó và chỉ đặt thuật ngữ phân loại
sách du lịch
Cho đến nay, tôi đã có thể thực hiện việc này thông qua plugin Đích tùy chỉnh chứ không chỉ với cấu hình di chuyển YAML.
Đây là những gì tôi hy vọng sẽ sử dụng:
uuid: d66124cf-232b-4080-911c-1d26aefd0246
mã ngôn ngữ: en
trạng thái: đúng
phụ thuộc: { }
id: quote_fornitore_voucher_csv_import
lớp: không
trường_plugin_method: null
cck_plugin_method: null
thẻ_di chuyển: null
migration_group: sách
nhãn: 'Nhập khẩu sách du lịch'
nguồn:
plugin: csv
đường dẫn: /Users/walter/travel_books.csv
dấu phân cách: ','
bao vây: '"'
tiêu đề_offset: 0
id:
- Tôi
lĩnh vực:
-
tên: id
nhãn: 'Id duy nhất'
-
tên: book_title
-
tên: đất nước
-
tên: trang
-
tên: tóm tắt
.....
hằng số:
travel_book: 'Sách du lịch'
tiến trình:
loại:
plugin: default_value
default_value: sách
field_pages: trang
trường_quốc gia: quốc gia
tiêu đề: book_title
trường_book_type:
plugin: thực thể_lookup
entity_type: taxonomy_term
gói: book_type
bundle_key: vid
nguồn: hằng số/travel_book
không:
plugin: thực thể_generate
entity_type: nút
gói: cuốn sách
bundle_key: loại
value_key: tiêu đề
nguồn: book_title
truy cập_kiểm tra: 0
điểm đến:
plugin: 'thực thể: nút'
ghi đè_properties:
- trường_trang
- lĩnh vực_quốc gia
di chuyển_phụ thuộc: null
Tôi có hai vấn đề với việc di chuyển này:
- Thậm chí nếu
thực thể_generate
tìm đúng nút hiện có cho sách hiện tại, Công cụ di chuyển vẫn cố TẠO một nút mới, với cùng một NID và tất nhiên là không thành công với Lỗi SQL lớn màu đỏ
23000]: Vi phạm ràng buộc về tính toàn vẹn: 1062 Mục nhập trùng lặp '2662' cho khóa 'PRIMARY': CHÈN VÀO "nút" ("nid", "vid", "type", "uuid", "langcode") GIÁ TRỊ (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4); Mảng
- Tôi khắc phục điều này, chỉ là không thể thêm vào Sách hiện có thuật ngữ phân loại chính xác vào danh sách
trường_book_type
.
Tôi đã tìm ra vấn đề với 1 là Thực thể có thực thiIsNew
đặt thành Đúng. Hoặc ít nhất đó là những gì tôi đã tìm thấy. Tôi đã viết một plugin đích, dựa trên cấu hình mới, có thể buộc thực thể mới được tạo bằng thi hànhIsNew = FALSE
và nó dường như hoạt động như mong đợi. Không tìm thấy sách du lịch trong Sách i nDrupal được tạo, trong khi sách đã tồn tại được cập nhật, với các trường trang
và quốc gia
cập nhật.
Đây là mã có liên quan, tôi nghĩ vậy.
lớp trừu tượng EntityBase triển khai EntityInterface {
...
chức năng công khai mới () {
return !empty($this->enforceIsNew) || !$this->id();
}
...
Mặc dù có một ID, được thiết lập bởi không có
quá trình, thực thiIsNew được đặt thành THẬT
và do đó isNew() trả về True.
<?php
không gian tên Drupal\migrate_books\Plugin\migrate\destination;
sử dụng Drupal\Core\Entity\Entity;
sử dụng Drupal\Core\Entity\EntityInterface;
sử dụng Drupal\di chuyển\Plugin\di chuyển\đích\EntityContentBase;
sử dụng Drupal\migrate\Plugin\MigrationInterface;
sử dụng Drupal\di chuyển\Row;
sử dụng Symfony\Component\DependencyInjection\ContainerInterface;
/**
* @MigrateDestination(
* id = "cập nhật_nút"
* )
*/
lớp UpdateNodeDestination mở rộng EntityContentBase {
/** chuỗi @var $entityType */
tĩnh công khai $entityType = 'nút';
cập nhật hàm được bảo vệEntity(EntityInterface $entity, Row $row) {
$entity = parent::updateEntity($entity, $row);
//kiểm tra tham số..
if(!empty($this->configuration['prefer_update']) && $this->configuration['prefer_update']){
// buộc KHÔNG thực thi MỚI. Điều này sẽ tránh chèn hai lần các nút đã có sẵn (điều này sẽ dẫn đến
// vi phạm tính toàn vẹn từ MySQL
$entity->enforceIsNew(FALSE);
}
trả lại thực thể $;
}
}
và YAMLS được thay đổi bằng plugin của tôi và thông số mới prefer_update
điểm đến:
plugin: update_node
prefer_update: true
ghi đè_properties:
- trường_trang
- lĩnh vực_quốc gia
nhưng dường như với tôi rằng nó nên đơn giản hơn thế. Tôi rõ ràng là thiếu một cái gì đó. Tôi chắc chắn đây là một trường hợp sử dụng khá chuẩn, vì vậy nó có thể/nên thực hiện được hoàn toàn trong YAML.
Thứ hai, tôi vẫn không thể thêm chính xác sách_type
vào danh sách các thẻ hiện có.
Nếu tôi thêm trường_book_type
đến overwrite_properties
, tất nhiên nó sẽ bị ghi đè và chúng ta mất tất cả các số hạng trước đó.
Tôi dường như không phải là cách cập nhật bằng cách thêm giá trị vào trường đa giá trị.
Bất kỳ giúp đỡ?
Cảm ơn
W