it-swarm.com.de

Wie ändere ich einen Feldtyp?

Ich habe einen Inhaltstyp mit einem field_maps, dessen Typ Text (normal, lang) ist. Ich musste es in Text (normal) ändern.

Also habe ich diese SQL-Anweisung gemacht:

ALTER TABLE node__field_maps MODIFY field_maps_value VARCHAR(200);

Es scheint, dass field_type in VARCHAR(200) geändert wurde, aber es gibt noch ein weiteres Problem: Auf den Registerkarten Inhaltstyp und Felder verwalten wird das Feld weiterhin als Text) angezeigt (schlicht, lang).

Wie ändere ich es in Text (normal)?

8
Hefi

Ich habe auch diese Art von Problem, das den Feldtyp mit vorhandenen Daten von einem zum anderen ändert. Wie @Eyal bereits erwähnt hat, können wir einen Update-Hook an schreiben

  1. exportieren Sie Daten aus einer Feldtabelle in eine Variable
  2. entfernen Sie die Felder aller Bundles
  3. fügen Sie neue Felder aller Bundles hinzu
  4. daten in Feldtabelle wiederherstellen

Hier ist das Codebeispiel

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

}

HINWEIS: Sichern Sie immer den DB- und Testcode, bevor Sie diesen Code ausführen

Andere Gedanken In meinem Fall haben wir auch Konfigurationen exportiert, was bedeutet, dass der Feldtyp und die Einstellungen auch in den Konfigurationsdateien field_storage_config, field_config, entity_form_display und entity_view_display enthalten sind . Daher müssen wir auch die Konfigurationseinstellungen in diesen Dateien aktualisieren. Ein einfacher Weg könnte sein:

  • klonen Sie Ihre Website
  • löschen Sie das Feld und fügen Sie ein Feld mit demselben Namen erneut in die Feldbenutzeroberfläche ein
  • export konfiguriert, um sie im Repo zu verwenden
  • stellen Sie sicher, dass die Konfigurations-UUID für das Feld und den Speicher nicht geändert wurde (ändern Sie die UUID zurück, falls dies der Fall war), um zu vermeiden, dass beim Import möglicherweise Daten entfernt werden.
  • import konfigurieren nach DB-Update und Cache wieder löschen

Dieser Code wurde von @drugan im Beitrag https://www.drupal.org/node/2816859 inspiriert

12
eric.chenchao