Как изменить настройки длины поля?

Я установил один раз на веб-сайт ограничение длины для поля. И теперь клиент хочет поместить больше символов в это поле.

Я не могу изменить максимальный размер из Drupal, потому что получаю следующее сообщение об ошибке:

  

В базе данных есть данные для этого поля. Настройки полей больше не могут быть изменены.

Однако должно быть решение. Должен ли я изменить его в базе данных (это поле реализовано модулем Field-collections )?

44 голоса | спросил Ek Kosmos 8 PM000000110000004731 2011, 23:36:47

7 ответов


84

Решение Dylan Tack является самым простым, но мне лично нравится изучать внутренние базы данных Drupal, чтобы видеть, как там управляются вещи.

Итак, если у вас есть текстовое поле, имя которого является полем_text из 10 символов, вы хотите вырасти до 25:

  • данные будут храниться в двух таблицах: field_data_field_text и field_revision_field_text
  • Определение
  • хранится в файле field_config для данных хранилища и поле_config_instance для каждого экземпляра этого поля (например, метки).

Теперь сделаем операцию на сердце.

  1. Измените определения столбцов таблиц данных:

     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. Измените столбец определение , это очень сложно, потому что оно хранится в BLOB , но это не то, что остановит вас для этого.

    • Освободите кишки этой вещи BLOB :

    SELECT CAST(`data` AS CHAR(10000) CHARACTER SET utf8) 
    FROM `field_config` WHERE field_name = 'field_text';
    
    • Это даст вам что-то вроде:

    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...
    
    • Это семейство PHP сериализованного , интересная часть - s:10:"max_length";s:2:"10";, это означает, что этот массив имеет свойство с именем max_length (имя которого представляет собой строку с 10 символами - следовательно, «s») значение которого равно 10 (это строка длиной 2 символа). Это довольно легко, не так ли?

    • Изменение его значения так же просто, как замена части s:2:"10" на s:2:"25". Будьте осторожны: , если ваше новое значение больше, вам нужно адаптировать часть «s», например, 100 будет s:3:"100", поскольку длина 100 3.

    • Давайте добавим это новое значение в БД, не забудьте сохранить целую строку.

    UPDATE `field_config` 
    SET data = 'a:7:{...a:2:{s:10:"max_length";s:2:"25";...}'
    WHERE `field_name` = 'field_text'
    
    • Промойте ваши кеши.
  3. ???
  4. PROFIT!

Кстати, PhpMyAdmin имеет некоторые настройки, позволяющие прямое изменение столбцов BLOB , но зачем идти простым путем?

PS: Это также может сэкономить вашу жизнь при размещении кода PHP в представлениях и получении WSOD из-за ошибки в вашем коде.

ответил tostinni 26 AM00000040000004331 2011, 04:02:43
17
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));
}
ответил Kevin Thompson 20 J000000Saturday13 2013, 00:55:02
9

Это, по-видимому, ограничение текущего текстового модуля. text_field_settings_form () имеет этот комментарий: « @todo : если $ has_data, добавьте обработчик проверки, который позволяет увеличивать max_length.".

В качестве временного обходного пути вы можете прокомментировать '#disabled' => $has_data в модулях /поле /modules /text /text.module, вокруг строки 77.

Я не мог найти существующую проблему для этого конкретного случая, но вы можете упомянуть ее на # 372330 .

ответил Dylan Tack 26 AM00000020000005131 2011, 02:03:51
6

Drupal 7

  

При создании текстового поля в Drupal 7 вы должны выбрать максимум   длина для ваших данных. Как только вы создадите данные для этого поля,   максимальная длина становится неизменной в настройках поля Drupal.

     

Понятно, что это будет отключено для уменьшения   максимальной длины, поскольку это может привести к потере данных, однако   должно быть возможно увеличить максимальную длину для любого поля.   todo в коде Drupal 7 Text module показывает, что это было предназначено, но   никогда не выполнялся.

     

3 вещи, которые должны произойти:

     
  1. Измените длину VARCHAR столбца значения в таблице field_data_ {имя_файла} таблицы
  2.   
  3. Измените длину VARCHAR столбца значения в таблице field_revision_ {fieldname}
  4.   
  5. Обновите конфигурацию поля, чтобы отобразить новое значение максимальной длины   Следующая функция выполняет все три из этих шагов и принимает 2 простых параметра, включая имя поля и новую максимальную длину.
  6.   
/**
 * 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();
}
  

Как только эта функция доступна в вашем установочном файле, вы можете создать новую функцию обновления базы данных, которая использует эту новую функцию для внесения необходимых изменений.

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

Источник: http://nathan.rambeck.org/блог /42-модификация-друпал-7-текст-поля максимальной длины


Drupal 8

Вот версия той же функции, предложенная @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
    );
  }
}
ответил kenorb 3 PMpThu, 03 Apr 2014 14:05:15 +040005Thursday 2014, 14:05:15
3

Попробуйте это ... это обновит тип данных полей от TEXT до LONG_TEXT и обновит max_length от 4000 до максимальной длины текста ... надеюсь, что это поможет.

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);    
  }
}
ответил Harold 30 J000000Monday12 2012, 16:39:28
2

D8

  1. Прокомментируйте две строки в core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchem‌​a.php
  2. В своем браузере перейдите к /admin/config/development/configuration/single/export. Тип конфигурации - «Полевое хранилище» и выберите соответствующее поле. Скопируйте конфигурацию.
  3. Перейдите к /admin/config/development/configuration/single/import. , Тип конфигурации - «Полевое хранилище». Вставьте конфигурацию. Измените длину.
  4. Отправить форму.

Заметьте (как вы, вероятно, уже знаете), если вы сократите длину, тогда существующие данные будут усечены.

ответил Dalin 20 +03002017-10-20T18:31:23+03:00312017bEurope/MoscowFri, 20 Oct 2017 18:31:23 +0300 2017, 18:31:23
1

В Drupal 7 я внес изменения в 2 таблицы в phpmyadmin и обновил кеш.

  1. "field_data_field_lorem": изменено "field_lorem_value" на "longtext"
  2. "field_config": изменено "type" на "text_long"
ответил Jill 12 PM00000090000002731 2011, 21:28:27

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132