web-dev-qa-db-ja.com

フィールドタイプを変更するにはどうすればよいですか?

field_mapsのコンテンツタイプがあり、そのタイプはText(plain、long)です。 Text(plain)に変更する必要がありました。

したがって、次のSQLステートメントを実行しました。

_ALTER TABLE node__field_maps MODIFY field_maps_value VARCHAR(200);
_

field_typeVARCHAR(200)に変更されたようですが、まだ問題が1つあります。コンテンツタイプと管理フィールドのタブで、フィールドがText (プレーン、ロング)

Text(plain)に変更するにはどうすればよいですか?

8
Hefi

既存のデータを使用してフィールドタイプを別のフィールドタイプに変更するこの種の問題も発生しています。 @Eyalが述べたように、更新フックを

  1. フィールドテーブルから変数にデータをエクスポートする
  2. すべてのバンドルのフィールドを削除する
  3. すべてのバンドルの新しいフィールドを追加する
  4. データをフィールドテーブルに復元する

これがコード例です

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();
    }
  }

}

注:このコードを実行する前に、常にDBとテストコードをバックアップしてください

その他の考え私の場合、構成もエクスポートしました。これは、フィールドタイプと設定がfield_storage_config、field_config、entity_form_display、およびentity_view_display構成ファイルにも含まれていることを意味します。したがって、これらのファイルの構成設定も更新する必要があります。簡単な方法は次のとおりです。

  • あなたのウェブサイトを複製する
  • フィールドを削除し、フィールドUIで同じ名前のフィールドを再度追加する
  • 構成をエクスポートしてリポジトリで使用する
  • インポートによってデータが削除される可能性をなくすために、フィールドとストレージの構成UUIDが変更されていないことを確認してください(変更されている場合はUUIDを元に戻します)。
  • dBの更新後に構成をインポートし、キャッシュを再度クリアする

これは、投稿の@druganに触発されたコードです https://www.drupal.org/node/2816859

12
eric.chenchao