Tôi cũng đã nhận được loại vấn đề này thay đổi loại trường từ loại này sang loại khác với dữ liệu hiện có. Vì vậy, như @Eyal đã đề cập, chúng ta có thể viết một bản cập nhật để
- xuất dữ liệu từ bảng trường sang biến
- loại bỏ các trường của tất cả các gói
- thêm các lĩnh vực mới của tất cả các gói
- khôi phục dữ liệu vào bảng trường
Đây là ví dụ mã
use \Drupal\field\Entity\FieldStorageConfig;
use \Drupal\field\Entity\FieldConfig;
/**
* Change node__field_maps from string_long to string type.
*/
function mymodule_update_8XXX() {
$database = \Drupal::database();
$table = 'node__field_maps';
$entity_type = 'node';
$field_name = 'field_maps';
$field_storage = FieldStorageConfig::loadByName($entity_type, $field_name);
if (is_null($field_storage)) {
return;
}
$rows = NULL;
if ($database->schema()->tableExists($table)) {
// The table data to restore after the update is completed.
$rows = $database->select($table, 'n')
->fields('n')
->execute()
->fetchAll();
}
$new_fields = array();
// Use existing field config for new field.
foreach ($field_storage->getBundles() as $bundle => $label) {
$field = FieldConfig::loadByName($entity_type, $bundle, $field_name);
$new_field = $field->toArray();
$new_field['field_type'] = 'string';
$new_field['settings'] = array();
$new_fields[] = $new_field;
}
// Deleting field storage which will also delete bundles(fields).
$new_field_storage = $field_storage->toArray();
$new_field_storage['type'] = 'string';
$new_field_storage['settings'] = array(
'max_length' => 255,
'is_ascii' => FALSE,
'case_sensitive' => FALSE,
);
$field_storage->delete();
// Purge field data now to allow new field and field_storage with same name
// to be created. You may need to increase batch size.
field_purge_batch(10);
// Create new field storage.
$new_field_storage = FieldStorageConfig::create($new_field_storage);
$new_field_storage->save();
// Create new fields.
foreach ($new_fields as $new_field) {
$new_field = FieldConfig::create($new_field);
$new_field->save();
}
// Restore existing data in the same table.
if (!is_null($rows)) {
foreach ($rows as $row) {
$database->insert($table)
->fields((array) $row)
->execute();
}
}
}
LƯU Ý: Luôn sao lưu DB và mã kiểm tra trước khi chạy mã này
Những suy nghĩ khác
Trong trường hợp của tôi, chúng tôi cũng đã xuất cấu hình, có nghĩa là loại trường và cài đặt cũng được bao gồm trong các tệp cấu hình field_st Storage_config, field_config, entity_form_display và entity_view_display. Vì vậy, chúng tôi phải cập nhật cài đặt cấu hình trong các tệp đó. Một cách dễ dàng có thể là:
- nhân bản trang web của bạn
- xóa trường và thêm một trường có cùng tên một lần nữa trong giao diện người dùng trường
- cấu hình xuất để sử dụng chúng trong repo
- đảm bảo cấu hình uuid cho trường và bộ lưu trữ không bị thay đổi (thay đổi lại uuid nếu có) để tránh việc nhập dữ liệu có khả năng xóa dữ liệu.
- nhập cấu hình sau khi cập nhật DB và xóa bộ nhớ cache một lần nữa
Đây là mã được lấy cảm hứng từ @drugan trong bài đăng https://www.drupal.org/node/2816859