Saha ayarlarının uzunluğu nasıl değiştirilir?


46

Bir web sitesine bir alan için bir uzunluk sınırı belirledim. Ve şimdi müşteri bu alana daha fazla karakter koymak istiyor.

Aşağıdaki hata iletisini alıyorum çünkü maksimum boyutu Drupal'dan değiştiremiyorum:

Veritabanında bu alan için veri var. Saha ayarları artık değiştirilemez.

Ancak bir çözüm olmalı. Bunu veritabanında değiştireyim mi (alan Alan koleksiyonları modülü tarafından uygulanan alandır )?


Drupal ve CCK'nın hangi versiyonunu söyleyebilir misiniz? Ayrıca herhangi bir CCK modülü katkıda bulunuyor mu?
Patrick

Drupal versiyonu 7'dir.
Ek Kosmos

Ve bunu içerik türü yönetimi alanları bölümünde değiştiremezsiniz? İstediğiniz noktada değiştirebilmelisiniz. Size bir uyarı verebilir, ancak yine de izin vermesi gerekir. Bu, saha koleksiyon modülünde hata / sınırlama olabilir.
Patrick

Alan gruplarını kullanmayı denediniz mi? Artık daha önce yapamadığınız grup çoğaltması gibi işlemleri yapabilirsiniz.
Patrick

İçerik türü yönetimi alanları bölümünde değiştiremiyorum! Mesele bu. Drupal yapmama izin verme.
Ek Kosmos

Yanıtlar:


89

Dylan Tack çözümü en kolay yoldur, ancak şahsen Drupal'ın veritabanının iç bölümlerini araştırıp orada işlerin nasıl yürüdüğünü görmek hoşuma gidiyor.

Bu nedenle, makine adının 25'e çıkarmak istediğiniz 10 karakterlik alan_metin olduğu bir metin alanına sahip olduğunuzu varsayalım:

  • veriler iki tabloda depolanacaktır: field_data_field_text ve field_revision_field_text
  • tanım, depolama verileri için field_config ve bu alanın her bir örneği için field_config_instance içinde saklanır (etiket benzeri şeyler).

Şimdi küçük bir kalp ameliyatı yapalım.

  1. Veri tablolarını değiştirdikten sonra sütun tanımları:

    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. Tanım sütununu değiştirin , bu çok zor çünkü bir BLOB'da saklanıyor , ancak bu sizi durduracak bir şey değil.

    • Bu BLOB olayının cesaretini yok et :

    SELECT CAST(`data` AS CHAR(10000) CHARACTER SET utf8) 
    FROM `field_config` WHERE field_name = 'field_text';
    • Bu size şöyle bir şey verecektir:

    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...
    • Bu bir PHP serileştirilmiş dizi, ilginç olan kısım, s:10:"max_length";s:2:"10";bu dizinin bu özelliğin max_length(10 karakterlik bir karakter dizesidir - bu nedenle "s") hangi değerin 10 (2 karakter uzunluğundaki bir karakter dizisi) olduğu bir özelliği olduğu anlamına gelir. Oldukça kolay değil mi?

    • Değerini değiştirmek, s:2:"10"parçayı değiştirmek kadar kolaydır s:2:"25". Dikkatli olun: yeni değeriniz daha uzunsa, "s" kısmını uyarlamanız gerekir, örneğin 100 koyarak s:3:"100"100 uzunluk 3 olacaktır.

    • Bu yeni değeri DB'ye geri koyalım, dizenin tamamını tutmayı unutmayın.

    UPDATE `field_config` 
    SET data = 'a:7:{...a:2:{s:10:"max_length";s:2:"25";...}'
    WHERE `field_name` = 'field_text'
    • Önbelleklerini yıka.
  3. ???

  4. KAR!

Bu arada, PhpMyAdmin, BLOB sütunlarının doğrudan değiştirilmesine izin veren bazı ayarlara sahiptir , ancak neden bu kadar kolay?

Not: Bu, görünümlerinize bazı PHP kodları koyarken ve kodunuzdaki bir hata nedeniyle WSOD aldığınızda da hayatınızı kurtarır.


Bu ilk SQL deyimi demeliyim ALTER TABLEdeğil SELECT TABLE. Ayrıca, şunu daha da temizleyebilirsiniz: ALTER TABLE field_data_field_text MODIFY field_text_value... (DEĞİŞTİR, adını değiştirmek istemiyorsanız DEĞİŞTİR gibi . Ve istemezsiniz.)
artfulrobot

4
Bunun için teşekkürler. Keşke vereceğim birden fazla oy hakkım olsaydı.
BC01

1
Bu gönderi aynı yaklaşımı elde etmek için Drupal'ın
Juampy NR

2
Serileştirilmiş verilerinizi internete göndermeyi sakıncası yoksa, bu aracı düzenleme için harika buldum: pines.sourceforge.net/phpserialeditor.php
Pete

'KARAKTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL' ile ilgili bir hata alırsanız, PhpMyAdmin'i kullanabilirsiniz.
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));
}

Bu düzeltme gibi en çok elle yapılan DB hackery güvenmiyor çünkü ... bir hook_update_N üzerinden tekrarlanabilir bir çözüm olması esastır!
areynolds

9

Bu, geçerli metin modülünün bir sınırlaması gibi görünüyor. text_field_settings_form () bu yorumu yaptı: " @todo : $ has_data ise, sadece max_length'in artmasına izin veren bir doğrulama işleyicisi ekleyin.".

Geçici bir çözüm olarak, '#disabled' => $has_datasatırlar 77 / civarı / field / module / text / text.module modüllerinde yorum yapabilirsiniz .

Bu özel durum için mevcut bir sorun bulamadım, ancak # 372330'dan bahsedebilirsiniz .


2
Cevabınız için teşekkürler. Çizgiyi yorumladım ve şimdi alandaki değeri değiştirebiliyorum, ancak sumbit sonrası aşağıdaki hatayı alıyorum:Attempt to update field Serial No failed: field_sql_storage cannot change the schema for an existing field with data..
Ek Kosmos

Drupal konuyu işlemekle ilgili olarak, lütfen devam et ve yap.
Ek Kosmos

1
Bunu işe alamadım. Bu çizgiyi yorumladıktan sonra hala ALTER TABLE'ın başarısız olduğu bir MYSQL hatası alıyorum.
jchwebdev

Bir tane alırsanız FieldUpdateForbiddenException: cannot change the schema for an existing field with data, L282 hakkında da yorum yapmanız gerekir modules/field/modules/field_sql_storage/field_sql_storage.module.
Dieuwe

@ dieuwe adlı kullanıcının yorumu yanlış. Bu dosya D8'in son sürümlerinde mevcut değil (eğer öyleyse). core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php"SQL depolama alanı mevcut bir alanın şemasını değiştiremez" metiniyle istisnalar atan iki satırı yorumlamanız gerekir . 1312 ve 1403 numaralı hatlar hakkında.
Dalin

6

Drupal 7

Drupal 7'de bir metin alanı oluştururken, verileriniz için maksimum uzunluğu seçmelisiniz. Bu alan için herhangi bir veri oluşturduğunuzda, maksimum uzunluk Drupal alan ayarlarında değişmez olur.

Bunun maksimum uzunluğu azaltmak için devre dışı bırakılacağı anlaşılabilir çünkü veri kaybına neden olabilir, ancak herhangi bir alan için maksimum uzunluğu artırmak mümkün olmalıdır. Drupal 7 Metin modülü kodundaki bir yapılacak işlem bunun amaçlandığını ancak asla gerçekleştirilemediğini gösterir.

Olması gereken 3 şey:

  1. Field_data_ {fieldname} tablosundaki değer sütununun VARCHAR uzunluğunu değiştirin
  2. Field_revision_ {fieldname} tablosundaki değer sütununun VARCHAR uzunluğunu değiştirin
  3. Yeni maksimum uzunluk ayarını yansıtacak şekilde alanın konfigürasyonunu güncelleyin Aşağıdaki fonksiyon, bu adımların 3'ünü de yerine getirir ve alanın adı ve yeni maksimum uzunluk dahil 2 kolay parametre alır.
/**
 * 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();
}

Bu fonksiyon özel kurulum dosyanızda mevcut olduğunda, gerekli değişiklikleri yapmak için bu yeni fonksiyonu kullanan yeni bir veritabanı güncelleme fonksiyonu oluşturabilirsiniz.

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

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


Drupal 8

İşte @Christopher tarafından önerilen aynı fonksiyonun sürümü :

/**
 * 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
Bir projede bu drupal 8 metodunu kullandık ve drush updb --entity-updatesbu fonksiyonda çalıştığımız alanları çalıştırdığınızda güncelleme gerektiren olarak işaretleneceği konularla karşılaştık . Daha sonra alan şemasını mysql ile tekrar güncellemeye çalışır. Bizim için bu, zaten saha verisi olduğu için başarısız olacaktır. Bu, diğer güncelleme görevlerinin çalışmasını engelliyordu.
leon.nk

Uzun lafın kısası, yeni alanlar oluşturmak ve verileri karşıya geçirmek muhtemelen daha güvenlidir.
leon.nk

3

Bunu deneyin ... bu, alan veri türünü METİN'ten LONG_TEXT'e ve max_length4000'den maksimum uzun metin uzunluğuna günceller ... bunun yardımcı olacağını umarız.

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 depolama alanı mevcut bir alan için şema değiştiremez" metiniyle istisnalar atan iki satırı yorumlayın. 1312 ve 1403 hatları hakkında.
  2. Tarayıcınızda, adresine gidin /admin/config/development/configuration/single/export. Konfigürasyon tipi "Field Storage" dır ve söz konusu alanı seçin. Yapılandırmayı kopyalayın.
  3. Git /admin/config/development/configuration/single/import. . Konfigürasyon tipi "Field Storage" dir. Yapılandırmayı yapıştırın. Uzunluğu değiştirin.
  4. Formu gönder.

Not (muhtemelen zaten bildiğiniz gibi), uzunluğu kısaltırsanız, mevcut veriler kesilecektir.


Bu bir cazibe gibi çalıştı. Drupal 8.5.3'ten itibaren, satırlar korumalı fonksiyon güncellemesinde 1505-1507, DedicatedTableSchema güncellemesinde ve 1596-1598, korumalı fonksiyon güncellemesindeSharedTableSchema'dır. Tamamlandığında geri döndüğünden emin ol! Teşekkür ederim.
HongPong

İlk önce bu yaklaşımı denedim. Paragraf alanını değiştirmeye çalışıyorum. Çalışır, ancak yine de ilgili tabloları ALTER için zorunludur.
Yaazkal

@Yaazkal Hmmm, bu benim deneyimim değildi. Alanı uzatmaya veya kısaltmaya mı çalışıyorsunuz?
Dalin

@Dalin 255'ten 510'a kadar uzar. D 8.5.5 ve Paragraf 1.3'ü kullanma
Yaazkal

1

Drupal 7'de, phpmyadmin'de 2 tablo üzerinde değişiklikler yaptım ve önbelleği yeniledim.

  1. "field_data_field_lorem": "field_lorem_value" yerine "longtext" olarak değiştirildi
  2. "field_config": "type" değiştirildi "text_long"

Bunu D7'ye yama olarak mı gönderdin? Bu gerçekten bir sorunsa, bu sorunu temel kodda çözmek için onlara gerçekten bir düzeltme eki vermelisiniz.
Patrick

Alan büyüklüğü değerimi phpmyadmin'den değiştirdim (10'dan 25'e kadar VARCHAR) ve önbelleği yeniledi, ancak işe yaramadı. Veritabanında VARCHAR (25) yağmalandı, ancak Drupal'da alan, 10'dan önceki maksimum boyut değerinde. Belki bazı gizli alan ayarları var?
Ek Kosmos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.