Drupal 7修改字段类型为varchar后无法正确保存字符串数据求助
问题原因分析与解决方案
这个问题我之前帮客户排查过类似的情况,核心原因是Drupal的Schema缓存机制以及模块Schema定义与数据库结构不同步导致的:
为什么会出现这个异常?
db_change_field()仅修改数据库,不更新模块Schema:你用db_change_field()成功修改了数据库字段类型,但这个API只负责操作数据库表结构,不会自动修改模块的hook_schema()定义,也不会主动清除Drupal的Schema缓存。- Drupal依赖缓存的Schema处理数据:
drupal_get_schema()默认读取的是缓存中的Schema信息,而非实时查询数据库。即使数据库已经更新,Drupal还是会用缓存里旧的int类型定义来处理实体数据——这就是保存时字符串被强制转成数字的原因:实体系统根据缓存的Schema判定该字段是int类型,自动做了类型转换(比如'8sf635'被截断为数字8,纯非数字字符串被转成0)。
解决步骤
1. 同步更新模块的Schema定义文件
找到你的自定义模块(或对应业务模块)的.install文件,定位到hook_schema()中dpp_bab_promotion表的promotion_id字段,将其定义修改为你需要的varchar格式:
function your_module_schema() { $schema['dpp_bab_promotion'] = array( // ...其他表结构定义 'fields' => array( 'promotion_id' => array( 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'description' => t('The ID of the promotion, found in'), ), // ...其他字段定义 ), // ...其他表设置 ); return $schema; }
这一步是核心,因为Drupal的Schema体系是以模块的hook_schema()为唯一权威来源的,后续的缓存重建、模块更新都会依赖这个定义。
2. 清除Drupal的Schema缓存
强制Drupal重新读取模块的Schema定义并更新缓存:
- 命令行方式(推荐):使用Drush执行
drush cache-clear schema(Drupal 7版本),或者直接清除所有缓存drush cc all - 后台界面方式:进入
配置 > 性能页面,点击「清除所有缓存」按钮
3. 验证修复效果
执行以下代码确认Schema是否更新:
drupal_get_schema('dpp_bab_promotion', TRUE);
这里的第二个参数TRUE表示强制刷新缓存,此时返回的Schema应该已经显示promotion_id为varchar类型了。之后再测试实体保存操作,'8sf635'或'qsfd7aer'应该能完整存入数据库。
额外提醒
以后做数据库结构变更时,一定要同步更新模块的hook_schema()定义,再清除缓存——这样才能保证Drupal的实体系统、表单系统等所有依赖Schema的组件都能正确识别字段类型,避免出现数据转换异常。
内容的提问来源于stack exchange,提问作者JimmyD
相关产品推荐
相关产品推荐

