필드 길이 설정을 변경하는 방법은 무엇입니까?


46

한 번 웹 사이트에 길이 제한을 설정했습니다. 이제 클라이언트는 해당 필드에 더 많은 문자를 넣고 싶어합니다.

다음 오류 메시지가 표시되어 Drupal에서 최대 크기를 변경할 수 없습니다.

데이터베이스에이 필드에 대한 데이터가 있습니다. 필드 설정을 더 이상 변경할 수 없습니다.

그러나 해결책이 있어야합니다. 데이터베이스에서 변경해야합니까 (필드는 Field-collections 모듈 에서 구현 된 것 입니까)?


Drupal과 CCK의 버전을 알려주시겠습니까? CCK contrib 모듈도 있습니까?
— Patrick

Drupal 버전은 7입니다.
— Ek Kosmos

콘텐츠 유형 관리 필드 섹션에서 수정할 수 없습니까? 언제든지 수정할 수 있어야합니다. 경고 메시지가 표시 될 수 있지만 여전히 허용해야합니다. 필드 콜렉션 모듈의 버그 / 제한 사항 일 수 있습니다.
— Patrick

필드 그룹을 사용해 보셨습니까? 이제 이전에는 불가능했던 그룹 복제와 같은 작업을 수행 할 수 있습니다.
— Patrick

콘텐츠 유형 관리 필드 섹션에서 수정할 수 없습니다! 이것이 요점입니다. Drupal은 그렇게하지 않습니다.
— Ek Kosmos

답변:


89

Dylan Tack 솔루션이 가장 쉽지만 개인적으로 Drupal 데이터베이스의 내부 병동을 탐색하여 사물이 어떻게 관리되는지 봅니다.

따라서 컴퓨터 이름이 field_text 인 10 자의 텍스트 필드가 25 자라 가정하면 :

  • 데이터는 field_data_field_text 및 field_revision_field_text의 두 테이블에 저장됩니다.
  • 정의는 스토리지 데이터의 경우 field_config에,이 필드의 각 인스턴스 (label과 같은 항목)의 field_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이됩니다.

    • 이 새로운 값을 DB에 다시 넣고 전체 문자열을 유지하는 것을 잊지 마십시오.

    UPDATE `field_config` 
    SET data = 'a:7:{...a:2:{s:10:"max_length";s:2:"25";...}'
    WHERE `field_name` = 'field_text'
    • 캐시를 비 웁니다.
  3. ???

  4. 이익!

그건 그렇고, PhpMyAdmin은 BLOB 열을 직접 수정할 수있는 설정이 있지만 왜 쉬운 방법입니까?

추신 : 이것은 또한 일부 PHP 코드를 뷰에 넣고 코드 오류로 인해 WSOD를 가져올 때 생명을 구할 수 있습니다.


첫 번째 SQL 문은 ALTER TABLE그렇지 않다고 말합니다 SELECT TABLE. 또한 다음과 같이 더 깔끔하게 만들 수 있습니다. ALTER TABLE field_data_field_text MODIFY field_text_value... ( 이름 을 바꾸고 싶지 않을 때 MODIFY는 CHANGE와 비슷 합니다.)
— artfulrobot

4
고마워 나는 둘 이상의 공감대를 주었으면 좋겠다.
— BC01

1
이 게시물은 Drupal의 Schema API를 사용하여 동일한 접근 방식을 달성합니다. up2technology.com/blog/converting-drupal-fields
— Juampy NR

2
직렬화 된 데이터를 인터넷으로 전송하는 데 신경 쓰지 않는다면이 도구를 사용하여 편집에 좋습니다. pines.sourceforge.net/phpserialeditor.php
— Pete

'CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL'에 대한 오류가 발생하면 PhpMyAdmin을 사용할 수 있습니다.
— tog22

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

수동 DB 해커에 의존하지 않기 때문에이 수정 프로그램과 가장 유사합니다 .hook_update_N을 통해 복제 가능한 솔루션을 갖는 것이 필수적입니다!
— areynolds

9

이것은 현재 텍스트 모듈의 제한으로 보입니다. text_field_settings_form () 에는 다음과 같은 주석이 있습니다. " @todo : $ has_data 인 경우 max_length 만 증가시킬 수있는 유효성 검사 핸들러를 추가하십시오.".

임시 해결 방법 '#disabled' => $has_data으로 모듈 / 필드 / 모듈 /text/text.module에서 줄 77 주위에 주석을 달 수 있습니다.

이 특정 사례에 대한 기존 문제를 찾을 수 없지만 # 372330 에서 언급 할 수 있습니다 .


2
답변 주셔서 감사합니다. 나는 라인에 주석을 달았으며 이제 필드에서 값을 수정할 수 있지만 Attempt to update field Serial No failed: field_sql_storage cannot change the schema for an existing field with data..
— sumbit

드루팔 문제를 저지르는 것과 관련하여 계속 진행하십시오.
— Ek Kosmos

1
나는 이것을 작동시키지 못했습니다. 해당 줄을 주석 처리 한 후에도 ALTER TABLE이 실패한 MYSQL 오류가 계속 발생합니다.
— jchwebdev

당신이 A를 얻는다면 당신은 FieldUpdateForbiddenException: cannot change the schema for an existing field with data또한 L282를 주석 처리해야합니다 modules/field/modules/field_sql_storage/field_sql_storage.module.
— dieuwe

@dieuwe의 의견이 잘못되었습니다. 해당 파일이 최신 버전의 D8에 존재하지 않습니다. core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php"SQL 스토리지가 기존 필드의 스키마를 변경할 수 없습니다"라는 텍스트로 예외를 던지는 두 줄을 주석 처리해야합니다 . 1312 행 및 1403 행 정보
— Dalin

6

드루팔 7

Drupal 7에서 텍스트 필드를 만들 때 데이터의 최대 길이를 선택해야합니다. 이 필드에 대한 데이터를 작성하자마자 Drupal 필드 설정에서 최대 길이를 변경할 수 없습니다.

데이터가 손실 될 수 있으므로 최대 길이를 줄이면이 ​​기능을 사용할 수 없지만 모든 필드의 최대 길이를 늘릴 수 있어야합니다. Drupal 7 Text 모듈 코드의 할 일은 이것이 의도되었지만 달성 된 적이 없다는 것을 보여줍니다.

발생해야하는 3 가지 사항 :

  1. field_data_ {fieldname} 테이블에서 값 열의 VARCHAR 길이를 변경하십시오.
  2. field_revision_ {fieldname} 테이블에서 값 열의 VARCHAR 길이를 변경하십시오.
  3. 새로운 최대 길이 설정을 반영하도록 필드 구성 업데이트 다음 기능은 이러한 3 단계를 모두 수행하며 필드 이름과 새로운 최대 길이를 포함하여 2 가지 쉬운 매개 변수를 사용합니다.
/**
 * 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/blog/42-modify-drupal-7-text-field-maximum-length


드루팔 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
    );
  }
}

1
우리는 프로젝트 에서이 drupal 8 방법을 사용 했으며이 drush updb --entity-updates기능을 통해 실행 한 필드를 실행할 때 업데이트가 필요한 것으로 표시되는 문제가 발생했습니다. 그런 다음 mysql에서 필드 스키마를 다시 업데이트하려고 시도합니다. 우리에게는 이미 현장 데이터가 있었기 때문에 실패했을 것입니다. 다른 업데이트 작업이 실행되지 않았습니다.
— leon.nk

간단히 말해 새 필드를 만들고 데이터를 마이그레이션하는 것이 더 안전 할 것입니다.
— leon.nk

3

이것을 시도하십시오 ... 이것은 필드 데이터 유형을 TEXT에서 LONG_TEXT로 업데이트하고 max_length4000에서 최대 긴 텍스트 길이로 업데이트합니다 ...이 도움이되기를 바랍니다.

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

D8

  1. core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchem‌​a.php"SQL 스토리지는 기존 필드의 스키마를 변경할 수 없습니다"라는 텍스트로 예외를 던지는 두 줄을 주석 처리하십시오 . 1312 행과 1403 행에 대하여.
  2. 브라우저에서로 이동하십시오 /admin/config/development/configuration/single/export. 구성 유형은 "Field Storage"이며 해당 필드를 선택하십시오. 구성을 복사하십시오.
  3. 로 이동하십시오 /admin/config/development/configuration/single/import. . 구성 유형은 "필드 스토리지"입니다. 구성을 붙여 넣습니다. 길이를 변경하십시오.
  4. 양식을 제출하십시오.

참고로 (아마도 이미 알고 있듯이) 길이를 줄이면 기존 데이터가 잘립니다.


이것은 매력처럼 작동했습니다. Drupal 8.5.3부터는 보호 함수 updateDedicatedTableSchema에서 1505-1507이고 보호 함수 updateSharedTableSchema에서 1596-1598입니다. 완료되면 다시 변경하십시오! 감사합니다.
— HongPong

나는 먼저이 접근법을 시도했다. 단락 필드를 수정하려고합니다. 작동하지만 어쨌든 해당 테이블을 변경해야합니다.
— Yaazkal

@ Yaakal 흠, 그건 내 경험이 아니 었습니다. 필드를 늘리거나 줄이려고합니까?
— Dalin

@Dalin은 255에서 510으로 길어졌다. D 8.5.5 및 단락 사용 1.3
— Yaazkal

1

Drupal 7에서는 phpmyadmin에서 2 개의 테이블을 수정하고 캐시를 새로 고쳤습니다.

  1. "field_data_field_lorem": "field_lorem_value"를 "longtext"로 변경했습니다
  2. "field_config": "type"을 "text_long"으로 변경했습니다

이 패치를 D7에 패치로 제출 했습니까? 이것이 실제로 문제라면 핵심 코드에서이 문제를 해결하기 위해 패치를 발행해야합니다.
— 패트릭

필드 크기 값을 phpmyadmin (VARCHAR 유형의 10에서 25로)에서 변경하고 캐시를 새로 고쳤지만 작동하지 않습니다. 데이터베이스에서 VARCHAR (25)를 유지하지만 Drupal에서 필드의 크기는 10과 동일합니다. 숨겨진 필드 설정이 있습니까?
— Ek 코스모스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.