Ruby Sequel中如何将所有created_at字段值提前10分钟?
解决数据表时间戳批量减去指定时长的报错问题
我来帮你搞定这个问题!你遇到的“incompatible data types in combination”错误,本质是因为你直接用:created_at - 600的写法,ORM没办法正确识别这是时间类型的运算,反而把它当成了普通数值或字符串操作,导致数据库层面的类型不匹配。
下面根据不同的ORM场景给你可行的解决方案:
如果你用的是Sequel ORM(你的代码风格很符合)
Sequel支持用原生SQL表达式或者内置的时间间隔方法来处理,两种方式都能解决问题:
- 方式一:用
Sequel.lit写原生SQL片段MyApp::Model::MyTable.update(created_at: Sequel.lit('created_at - interval \'10 minutes\'')) - 方式二:用Sequel的
interval方法更优雅地实现MyApp::Model::MyTable.update(created_at: :created_at - Sequel.interval(minutes: 10))
如果你用的是Ruby on Rails的ActiveRecord
ActiveRecord可以通过Arel构建安全的表达式,或者直接写原生SQL:
- 方式一:用Arel构建类型安全的运算
MyTable.update_all(MyTable.arel_table[:created_at] - 600) - 方式二:针对不同数据库写原生SQL(更直观)
PostgreSQL/MariaDB通用写法:
MySQL专属写法:MyTable.update_all("created_at = created_at - INTERVAL '10 minutes'")MyTable.update_all("created_at = DATE_SUB(created_at, INTERVAL 10 MINUTE)")
通用原生SQL方案(适配所有数据库)
如果不想依赖ORM的语法,直接执行原生SQL是最稳妥的,根据你的数据库类型选择:
- PostgreSQL:
UPDATE my_table SET created_at = created_at - INTERVAL '10 minutes'; - MySQL/MariaDB:
UPDATE my_table SET created_at = DATE_SUB(created_at, INTERVAL 10 MINUTE); - SQLite:
UPDATE my_table SET created_at = datetime(created_at, '-10 minutes');
小提醒
执行批量更新前,一定要先备份数据,或者用LIMIT子句先测试更新少量数据,确认结果符合预期再全量执行哦!
内容的提问来源于stack exchange,提问作者theGreenCabbage
相关产品推荐
相关产品推荐

