it-swarm-id.com

Bagaimana cara mengubah panjang pengaturan bidang?

Saya telah menetapkan batas panjang untuk sebuah situs web pada suatu waktu. Dan sekarang klien ingin menempatkan lebih banyak karakter ke bidang itu.

Saya tidak dapat mengubah ukuran maksimum dari Drupal karena saya mendapatkan pesan kesalahan berikut:

Ada data untuk bidang ini dalam database. Pengaturan bidang tidak lagi dapat diubah.

Namun harus ada solusinya. Haruskah saya mengubahnya dalam basis data (bidang ini adalah salah satu yang diimplementasikan oleh modul Field-collections )?

47
Ek Kosmos

Solusi Dylan Tack adalah yang termudah, tetapi secara pribadi saya menikmati menjelajahi bangsal dalam basis data Drupal untuk melihat bagaimana segala sesuatu dikelola di sana.

Jadi, anggap Anda memiliki bidang teks yang nama mesinnya adalah field_text dengan 10 karakter yang ingin Anda kembangkan menjadi 25:

  • data akan disimpan dalam dua tabel: field_data_field_text dan field_revision_field_text
  • definisi disimpan di field_config untuk data penyimpanan, dan field_config_instance untuk setiap instance bidang ini (hal-hal seperti label).

Sekarang mari kita lakukan operasi jantung kecil.

  1. Ubah definisi kolom tabel data:

    ALTER TABLE `field_data_field_text` 
    CHANGE `field_text_value` `field_text_value` VARCHAR( 25 ) 
    CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;
    
    ALTER TABLE `field_revision_field_text` 
    CHANGE `field_text_value` `field_text_value` VARCHAR( 25 ) 
    CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;
    
  2. Ubah kolom definition , yang ini sangat sulit karena disimpan dalam gumpalan [~ # ~] gumpalan [~ # ~], tapi itu bukan sesuatu yang akan menghentikan Anda untuk melakukan ini.

    • Membedah nyali dari ini [~ # ~] gumpalan [~ # ~] hal:
    SELECT CAST(`data` AS CHAR(10000) CHARACTER SET utf8) 
    FROM `field_config` WHERE field_name = 'field_text';
    
    • Ini akan memberi Anda sesuatu seperti:
    a:7:{s:12:"translatable";s:1:"1";s:12:"entity_types";a:0:{}s:8:"settings";a:2:
        {s:10:"max_length";s:2:"10";s:17:"field_permissions";a:5:
        //a lot more stuff...
    
    • Ini adalah array PHP serial , yang menarik adalah s:10:"max_length";s:2:"10";, ini berarti array ini memiliki properti bernama max_length (yang namanya string 10 karakter - maka "s") yang nilainya 10 (yang merupakan string panjang 2 karakter). Cukup mudah, bukan?

    • Mengubah nilainya semudah mengganti s:2:"10" sebagian demi s:2:"25". Hati-hati: jika nilai baru Anda lebih lama Anda harus menyesuaikan bagian "s", misalnya menempatkan 100 akan menjadi s:3:"100" karena panjang 100 adalah 3.

    • Mari kita kembalikan nilai baru ini ke dalam DB, jangan lupa untuk menyimpan seluruh string.

    UPDATE `field_config` 
    SET data = 'a:7:{...a:2:{s:10:"max_length";s:2:"25";...}'
    WHERE `field_name` = 'field_text'
    
    • Siram cache Anda.
  3. ???

  4. KEUNTUNGAN!

Ngomong-ngomong, PhpMyAdmin memiliki beberapa pengaturan untuk mengizinkan modifikasi langsung kolom BLOB , tapi mengapa pergi dengan cara mudah?

PS: Ini juga bisa menyelamatkan hidup Anda ketika menaruh beberapa kode PHP dalam tampilan dan mendapatkan WSOD karena kesalahan dalam kode Anda.

89
tostinni
function mymodule_update_7100() {
  $items = array();
  _field_maxlength_fix('field_name');
  return $items;
}

function _field_maxlength_fix($field_name, $maxlength = 255) {
  _alter_field_table($field_name, $maxlength);
  $data = _get_field_data($field_name);
  $data = _fix_field_data($data, $maxlength);
  _update_field_config($data, $field_name);
}

function _alter_field_table($field_name, $maxlength) {
  db_query("ALTER TABLE field_data_".$field_name." CHANGE ".$field_name."_value ".$field_name."_value VARCHAR( ".$maxlength." ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL");
  db_query("ALTER TABLE field_revision_".$field_name." CHANGE ".$field_name."_value ".$field_name."_value VARCHAR( ".$maxlength." ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL");
}

function _get_field_data($field_name) {
  $qry = "SELECT data FROM field_config WHERE field_name = :field_name";
  $result = db_query($qry, array(':field_name' => $field_name))->fetchObject();
  return unserialize($result->data);
}

function _fix_field_data($data, $maxlength) {
  $data['settings']['max_length'] = (string)$maxlength;
  return serialize($data);
}

function _update_field_config($data, $field_name) {
  $qry = "UPDATE field_config SET data = :data WHERE field_name = :field_name";
  db_query($qry, array(':data' => $data, ':field_name' => $field_name));
}
20
Kevin Thompson

Ini tampaknya menjadi batasan modul teks saat ini. text_field_settings_form () memiliki komentar ini: " @ todo : Jika $ has_data, tambahkan validator handler yang hanya memungkinkan max_length untuk bertambah . ".

Sebagai solusi sementara, Anda dapat berkomentar '#disabled' => $has_data dalam modul/bidang/modul/teks/text.module, sekitar baris 77.

Saya tidak dapat menemukan masalah yang ada untuk kasus khusus ini, tetapi Anda mungkin menyebutkannya pada # 3723 .

9
Dylan Tack

Drupal 7

Saat membuat bidang teks di Drupal 7, Anda harus memilih panjang maksimum untuk data Anda. Segera setelah Anda membuat data apa pun untuk bidang ini, panjang maksimum menjadi tidak dapat diubah di Drupal pengaturan bidang.

Dapat dimengerti bahwa ini akan dinonaktifkan untuk mengurangi panjang maksimum karena bisa mengakibatkan hilangnya data, namun, harus mungkin untuk menambah panjang maksimum untuk bidang apa pun. Sebuah todo dalam Drupal 7 Kode modul teks menunjukkan ini dimaksudkan tetapi tidak pernah selesai.

3 hal yang perlu terjadi:

  1. Ubah panjang VARCHAR dari kolom nilai di tabel field_data_ {fieldname}
  2. Ubah panjang VARCHAR dari kolom nilai di tabel field_revision_ {fieldname}
  3. Perbarui konfigurasi bidang untuk mencerminkan pengaturan panjang maks baru. Fungsi berikut menyelesaikan 3 langkah ini dan mengambil 2 parameter mudah termasuk nama bidang dan panjang maksimum baru.
/**
 * Helper function to change the max length of a text field.
 */
function MYMODULE_change_text_field_max_length($field_name, $new_length) {
  $field_table = 'field_data_' . $field_name;
  $field_revision_table = 'field_revision_' . $field_name;
  $field_column = $field_name . '_value';

  // Alter value field length in fields table.
  db_query("UPDATE `{$field_table}` SET `{$field_column}`=SUBSTR(`{$field_column}`, 0, {$new_length})");
  db_query("ALTER TABLE `{$field_table}` CHANGE `{$field_column}` `{$field_column}` VARCHAR( {$new_length} )");
  // Alter value field length in fields revision table.
  db_query("UPDATE `{$field_revision_table}` SET `{$field_column}`=SUBSTR(`{$field_column}`, 0, {$new_length})");
  db_query("ALTER TABLE `{$field_revision_table}` CHANGE `{$field_column}` `{$field_column}` VARCHAR( {$new_length} )");

  // Update field config with new max length.
  $result = db_query("SELECT CAST(`data` AS CHAR(10000) CHARACTER SET utf8) FROM `field_config` WHERE field_name = '{$field_name}'");
  $config = $result->fetchField();
  $config_array = unserialize($config);
  $config_array['settings']['max_length'] = $new_length;
  $config = serialize($config_array);
  db_update('field_config')
    ->fields(array('data' => $config))
    ->condition('field_name', $field_name)
    ->execute();
}

Setelah fungsi ini tersedia di file instal kustom Anda, Anda dapat membuat fungsi pembaruan basis data baru yang menggunakan fungsi baru ini untuk membuat perubahan yang diperlukan.

/**
 * Change max_length of Name field
 */
function mymodule_update_7002() {
  MYMODULE_change_text_field_max_length('field_name', 50);
}

Sumber: http://nathan.rambeck.org/blog/42-modify-drupal-7-text-field-maximum-length


Drupal 8

Ini adalah versi dari fungsi yang sama yang diusulkan oleh @ Christopher :

/**
 * Utility to change the max length of a text field.
 *
 * @param string $field_name
 *   Field name. 
 * @param int $new_length
 *   Field length in characters. 
 *
 * @throws \DrupalUpdateException
 */
function MYMODULE_change_text_field_max_length($field_name, $new_length) {
  // The transaction opens here. 
  $txn = db_transaction();

  try {
    // Update field content tables with new max length.
    foreach (['field_data_', 'field_revision_'] as $prefix) {
      db_query('
      ALTER TABLE {' . $prefix . $field_name . '} 
        MODIFY ' . $field_name . '_value VARCHAR( ' . $new_length . ' )
      ');
    }

    // Update field config record with new max length.
    $result = db_query("
        SELECT CAST(data AS CHAR(10000) CHARACTER SET utf8) 
        FROM {field_config} 
        WHERE field_name = :field_name
      ", [':field_name' => $field_name]
    );
    $config = $result->fetchField();
    if ($config) {
      $config_array = unserialize($config);
      $config_array['settings']['max_length'] = $new_length;
      $new_config = serialize($config_array);
      db_update('field_config')
        ->fields(['data' => $new_config])
        ->condition('field_name', $field_name)
        ->execute();
    }
  }
  catch (Exception $e) {
    // Something went wrong somewhere, so roll back now.
    $txn->rollback();
    // Allow update to be re-run when errors are fixed.
    throw new \DrupalUpdateException(
      "Failed to change $field_name field max length: " . $e->getMessage(),
      $e->getCode(), $e
    );
  }
}
7
kenorb

Coba ini ... ini akan memperbarui tipe data bidang dari TEXT ke LONG_TEXT dan memperbarui max_length dari 4000 hingga panjang teks maksimal ... semoga ini membantu.

function my_module_update_1001(&$sandbox) {
  // Check if our field is already created.
  if (field_info_field('sample_text_field')) {
    db_query('ALTER TABLE field_data_sample_text_field CHANGE sample_text_field_value sample_text_field_value LONGTEXT');
    db_query('ALTER TABLE field_revision_sample_text_field CHANGE sample_text_field_value sample_text_field_value LONGTEXT');
    db_query("UPDATE field_config SET type = 'text_long' WHERE field_name = 'sample_text_field' ");

    $field = array(
      'field_name' => 'sample_text_field',
      'type' => 'text_long',
      'cardinality' => 1,
      'settings' => array(
         'max_length' => 0,
      ),
    );
    field_update_field($field);    
  }
}
3
Harold

D8

  1. Komentari dua baris dalam core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchem‌​a.php yang melempar pengecualian dengan teks "Penyimpanan SQL tidak dapat mengubah skema untuk bidang yang ada". Tentang garis 1312 dan 1403.
  2. Di browser Anda, navigasikan ke /admin/config/development/configuration/single/export. Jenis konfigurasi adalah "Bidang Penyimpanan", dan pilih bidang yang dimaksud. Salin konfigurasinya.
  3. Navigasi ke /admin/config/development/configuration/single/import. . Jenis konfigurasi adalah "Bidang Penyimpanan". Rekatkan konfigurasi. Ubah panjangnya.
  4. Kirimkan formulir.

Catatan (seperti yang mungkin sudah Anda ketahui), jika Anda mempersingkat panjangnya, maka data yang ada akan terpotong.

3
Dalin

Dalam Drupal 7, saya membuat modifikasi ke 2 tabel di phpmyadmin, dan menyegarkan cache.

  1. "field_data_field_lorem": berubah "field_lorem_value" menjadi "longtext"
  2. "field_config": diubah "ketik" menjadi "text_long"
1
Jill