私は一度ウェブサイトにフィールドの長さ制限を設定しました。そして今、クライアントはそのフィールドにより多くの文字を入れたいと思っています。
次のエラーメッセージが表示されるため、Drupalから最大サイズを変更できません。
データベースにこのフィールドのデータがあります。フィールド設定は変更できなくなりました。
ただし、解決策が必要です。データベースで変更しますか(フィールドは、Field-collectionsモジュールによって実装されたものです)?
私は一度ウェブサイトにフィールドの長さ制限を設定しました。そして今、クライアントはそのフィールドにより多くの文字を入れたいと思っています。
次のエラーメッセージが表示されるため、Drupalから最大サイズを変更できません。
データベースにこのフィールドのデータがあります。フィールド設定は変更できなくなりました。
ただし、解決策が必要です。データベースで変更しますか(フィールドは、Field-collectionsモジュールによって実装されたものです)?
回答:
Dylan Tackソリューションは最も簡単ですが、個人的には、Drupalのデータベースの内部を探索して、そこでの管理方法を確認するのを楽しんでいます。
そのため、マシン名が10文字のfield_textであるテキストフィールドがあると仮定して、25に拡大します。
それでは、少し心臓手術をしましょう。
データテーブルの列定義を変更します。
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;
定義列を変更します。これは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'
???
利益!
ちなみに、PhpMyAdminにはBLOB列の直接変更を許可する設定がありますが、なぜ簡単な方法がありますか?
PS:これは、コードにエラーがあるために、ビューにPHPコードを入れてWSODを取得するときの命も救うことができます。
ALTER TABLE
はありませんSELECT TABLE
。また、あなたはクリーナーのようなことを行うことができますALTER TABLE field_data_field_text MODIFY field_text_value
...(あなたが変更したくない場合にMODIFYは、CHANGEのようなものです名前をそして、あなたはしないでください。)
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));
}
これは、現在のテキストモジュールの制限のようです。 text_field_settings_form()には次のコメントがあります: " @todo:$ has_dataの場合、max_lengthの増加のみを許可する検証ハンドラーを追加します。"
一時的な回避策として、'#disabled' => $has_data
modules / field / modules / text / text.moduleの77行目でコメントアウトできます。
この特定のケースに関する既存の問題は見つかりませんでしたが、#372330で言及するかもしれません。
Attempt to update field Serial No failed: field_sql_storage cannot change the schema for an existing field with data..
FieldUpdateForbiddenException: cannot change the schema for an existing field with data
L282でコメントアウトする必要もありますmodules/field/modules/field_sql_storage/field_sql_storage.module
。
core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
「SQLストレージは既存のフィールドのスキーマを変更できません」というテキストで例外をスローする2行をコメント化する必要があります。1312行目と1403行目について
Drupal 7
Drupal 7でテキストフィールドを作成する場合、データの最大長を選択する必要があります。このフィールドのデータを作成するとすぐに、Drupalフィールドの設定で最大長が不変になります。
データの損失につながる可能性があるため、これが最大長を減らすために無効にされることは理解できますが、任意のフィールドの最大長を増やすことは可能です。Drupal 7 Textモジュールコードのtodoは、これが意図されていたが、決して達成されなかったことを示しています。
発生する必要がある3つのこと:
- field_data_ {fieldname}テーブルの値列のVARCHAR長を変更します
- field_revision_ {fieldname}テーブルの値列のVARCHAR長を変更します
- 新しい最大長の設定を反映するようにフィールドの構成を更新します。次の機能は、これらの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
@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
);
}
}
drush updb --entity-updates
ため、フィールドを実行すると、この関数を実行したときに更新が必要とマークされます。その後、mysqlでフィールドスキーマを再度更新しようとします。この場合、フィールドデータが既に存在するため、これは失敗します。これは、他の更新タスクの実行を妨げていました。
これを試してください...これにより、フィールドのデータ型が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);
}
}
D8
core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
「SQLストレージは既存のフィールドのスキーマを変更できません」というテキストで例外をスローする2行をコメント化します。行1312および1403について。/admin/config/development/configuration/single/export
ます。構成タイプは「フィールドストレージ」であり、問題のフィールドを選択します。構成をコピーします。/admin/config/development/configuration/single/import
ます。。構成タイプは「フィールドストレージ」です。構成を貼り付けます。長さを変更します。注(おそらく既にご存知のとおり)、長さを短くすると、既存のデータは切り捨てられます。
Drupal 7では、phpmyadminの2つのテーブルに変更を加え、キャッシュを更新しました。