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


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.