我曾经为网站设置了一个字段的最大限制。现在,客户希望在该字段中添加更多字符。
我无法从Drupal更改最大大小,因为我收到以下错误消息:
数据库中有此字段的数据。字段设置不能再更改。
但是,必须有一个解决方案。我是否应该在数据库中更改它(该字段是由Field-collections模块实现的)?
我曾经为网站设置了一个字段的最大限制。现在,客户希望在该字段中添加更多字符。
我无法从Drupal更改最大大小,因为我收到以下错误消息:
数据库中有此字段的数据。字段设置不能再更改。
但是,必须有一个解决方案。我是否应该在数据库中更改它(该字段是由Field-collections模块实现的)?
Answers:
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。
让我们将此新值放回数据库中,不要忘记保留整个字符串。
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
...(当您不想更改名称时,“修改”就像“更改”。您也不想这样做。)
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
在第77行附近的modules / field / modules / text / text.module中注释掉。
我找不到针对此特定案例的现有问题,但您可能会在#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存储无法更改现有字段的模式” 注释掉引发异常的两行。关于1312和1403号线。–
Drupal 7
在Drupal 7中创建文本字段时,必须选择数据的最大长度。为该字段创建任何数据后,最大长度在Drupal字段设置中将变为不变。
可以理解,为减少最大长度将禁用此功能,因为这可能会导致数据丢失,但是,应该可以增加任何字段的最大长度。Drupal 7文本模块代码中的待办事项表明这是有意的,但从未实现。
需要发生的三件事:
- 更改field_data_ {fieldname}表中value列的VARCHAR长度
- 更改field_revision_ {fieldname}表中value列的VARCHAR长度
- 更新字段的配置以反映新的最大长度设置以下功能完成所有这三个步骤,并采用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存储不能更改现有字段的架构” 注释掉引发异常的两行。关于1312和1403行。/admin/config/development/configuration/single/export
。配置类型为“字段存储”,然后选择有问题的字段。复制配置。/admin/config/development/configuration/single/import
。。配置类型为“字段存储”。粘贴配置。更改长度。注意(您可能已经知道),如果缩短长度,那么现有数据将被截断。
在Drupal 7中,我对phpmyadmin中的2个表进行了修改,并刷新了缓存。