it-swarm-vi.com

Làm cách nào để thay đổi độ dài của cài đặt trường?

Tôi đã đặt một lần cho một trang web một giới hạn chiều dài cho một lĩnh vực. Và bây giờ khách hàng muốn đưa thêm nhân vật vào lĩnh vực đó.

Tôi không thể thay đổi kích thước tối đa từ Drupal vì tôi nhận được thông báo lỗi sau:

Có dữ liệu cho lĩnh vực này trong cơ sở dữ liệu. Các thiết lập trường không còn có thể thay đổi.

Tuy nhiên phải có một giải pháp. Tôi có nên thay đổi nó trong cơ sở dữ liệu (trường được thực hiện bởi mô đun Bộ sưu tập trường ) không?

47
Ek Kosmos

Giải pháp Dylan Tack là dễ nhất, nhưng cá nhân tôi thích khám phá các phường bên trong cơ sở dữ liệu của Drupal để xem mọi thứ được quản lý ở dưới đó như thế nào.

Vì vậy, giả sử bạn có một trường văn bản có tên máy là trường văn bản gồm 10 ký tự bạn muốn tăng lên 25:

  • dữ liệu sẽ được lưu trữ trong hai bảng: field_data_fieldigin và field_Vvision_field bản
  • định nghĩa được lưu trữ trong field_config cho dữ liệu lưu trữ và field_config_instance cho từng phiên bản của trường này (thứ như nhãn).

Bây giờ chúng ta hãy làm một chút phẫu thuật tim.

  1. Thay đổi các định nghĩa cột bảng dữ liệu:

    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. Thay đổi cột định nghĩa , cột này rất khó vì nó được lưu trữ trong a [~ # ~] blob [~ # ~], nhưng đó không phải là thứ sẽ ngăn bạn làm điều này.

    • Phân tích can đảm của điều này [~ # ~] blob [~ # ~] điều:
    SELECT CAST(`data` AS CHAR(10000) CHARACTER SET utf8) 
    FROM `field_config` WHERE field_name = 'field_text';
    
    • Điều này sẽ cung cấp cho bạn một cái gì đó như:
    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...
    
    • Đây là một mảng PHP được tuần tự hóa mảng, phần thú vị là s:10:"max_length";s:2:"10";, điều này có nghĩa là mảng này có thuộc tính có tên max_length (tên là một chuỗi 10 ký tự - do đó "s") có giá trị là 10 (là một chuỗi dài 2 ký tự). Nó khá dễ, phải không?

    • Thay đổi giá trị của nó cũng dễ như thay thế s:2:"10" phần bởi s:2:"25". Hãy cẩn thận: nếu giá trị mới của bạn dài hơn, bạn phải điều chỉnh phần "s", ví dụ: đặt 100 sẽ là s:3:"100" như 100 chiều dài là 3.

    • Hãy đặt lại giá trị mới này trong DB, đừng quên giữ toàn bộ chuỗi.

    UPDATE `field_config` 
    SET data = 'a:7:{...a:2:{s:10:"max_length";s:2:"25";...}'
    WHERE `field_name` = 'field_text'
    
    • Xóa bộ nhớ cache của bạn.
  3. ???

  4. LỢI NHUẬN!

Nhân tiện, PhpMyAdmin có một số cài đặt để cho phép sửa đổi trực tiếp các cột BLOB , nhưng tại sao lại đi theo cách dễ dàng?

PS: Điều này cũng có thể cứu mạng bạn khi đặt một số PHP trong các khung nhìn và nhận WSOD do lỗi trong mã của bạn.

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

Điều này dường như là một hạn chế của mô-đun văn bản hiện tại. text_field_sinstall_form () có nhận xét này: " @ todo : Nếu $ has_data, hãy thêm trình xử lý xác thực chỉ cho phép tăng max_length . ".

Như một cách giải quyết tạm thời, bạn có thể nhận xét '#disabled' => $has_data trong các mô-đun/trường/mô-đun/văn bản/text.module, xung quanh dòng 77.

Tôi không thể tìm thấy sự cố hiện tại cho trường hợp cụ thể này, nhưng bạn có thể đề cập đến vấn đề này trên # 3723 .

9
Dylan Tack

Drupal 7

Khi tạo trường văn bản trong Drupal 7, bạn phải chọn độ dài tối đa cho dữ liệu của mình. Ngay khi bạn tạo bất kỳ dữ liệu nào cho trường này, độ dài tối đa sẽ không thay đổi trong Drupal.

Có thể hiểu rằng điều này sẽ bị vô hiệu hóa khi giảm độ dài tối đa vì nó có thể dẫn đến mất dữ liệu, tuy nhiên, có thể tăng độ dài tối đa cho bất kỳ trường nào. Một việc cần làm trong Drupal 7 Mã mô-đun văn bản cho thấy điều này đã được dự định nhưng không bao giờ được thực hiện.

3 điều cần phải xảy ra:

  1. Thay đổi độ dài VARCHAR của cột giá trị trong bảng field_data_ {fieldname}
  2. Thay đổi độ dài VARCHAR của cột giá trị trong bảng field_Vvision_ {fieldname}
  3. Cập nhật cấu hình của trường để phản ánh cài đặt độ dài tối đa mới Chức năng sau đây thực hiện cả 3 bước này và có 2 tham số dễ dàng bao gồm tên của trường và độ dài tối đa mới.
/**
 * 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();
}

Khi chức năng này có sẵn trong tệp cài đặt tùy chỉnh của bạn, bạn có thể tạo một chức năng cập nhật cơ sở dữ liệu mới sử dụng chức năng mới này để thực hiện các thay đổi cần thiết của bạn.

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

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


Drupal 8

Đây là phiên bản của chức năng tương tự được đề xuất bởi @ 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

Hãy thử điều này ... điều này sẽ cập nhật kiểu dữ liệu trường từ TEXT thành LONG_TEXT và cập nhật max_length từ 4000 đến độ dài văn bản dài tối đa ... hy vọng điều này sẽ giúp.

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. Nhận xét hai dòng trong core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchem‌​a.php ném ngoại lệ với văn bản "Bộ lưu trữ SQL không thể thay đổi lược đồ cho trường hiện có". Về dòng 1312 và 1403.
  2. Trong trình duyệt của bạn, điều hướng đến /admin/config/development/configuration/single/export. Loại cấu hình là "Lưu trữ trường" và chọn trường được đề cập. Sao chép cấu hình.
  3. Hướng đến /admin/config/development/configuration/single/import. . Loại cấu hình là "Lưu trữ trường". Dán cấu hình. Thay đổi độ dài.
  4. Gửi mẫu đơn.

Lưu ý (như bạn có thể đã biết), nếu bạn rút ngắn thời lượng, thì dữ liệu hiện tại sẽ bị cắt ngắn.

3
Dalin

Trong Drupal 7, tôi đã sửa đổi 2 bảng trong phpmyadmin và làm mới bộ đệm.

  1. "field_data_field_lorem": đã thay đổi "field_lorem_value" thành "longtext"
  2. "field_config": đã thay đổi "loại" thành "text_long"
1
Jill