Knex.js更新SQLite时存入[object Object]而非JSON字符串问题
Knex.js + SQLite 更新JSON字段时存入[object Object]的问题
我用Knex.js搭配SQLite数据库,执行insert创建条目时,JSON字段能正确转为字符串;但用update更新时,数据库列里存的却是[object Object]。
场景复现
表结构
card表包含:
- id(int)
- name(string)
- service(string)
插入操作及结果
插入代码:
const value = { name: 'test name', service: { domain: 'test domain' } } knex('card').insert(value).returning('*');
插入后数据库数据:
| id | name | service |
|---|---|---|
| 1 | test | {"domain":"test domain"} |
更新操作及结果
更新代码:
const updateValue = { name: 'test name', service: { domain: 'updated domain' } } knex('card').where('id', 1).update(updateValue).returning('*');
更新后数据库数据:
| id | name | service |
|---|---|---|
| 1 | test | [object Object] |
我需要service列保持JSON字符串化的版本,方便前端解析。已经用极简环境排查,插入和更新的输入对象格式一致,但不清楚更新失败的原因,这是预期行为吗?
原因及解决方法
原因
Knex对insert和update的字段处理逻辑存在差异:insert时会自动检测对象类型并将其序列化为JSON字符串(针对SQLite的string列),但update操作不会自动执行这个序列化步骤,而是直接调用对象的toString()方法,最终存入[object Object]。
解决方式
1. 手动序列化JSON
更新时手动将service对象转为JSON字符串:
const updateValue = { name: 'test name', service: JSON.stringify({ domain: 'updated domain' }) } knex('card').where('id', 1).update(updateValue).returning('*');
2. 使用Knex内置方法处理
利用Knex提供的json方法或raw语句,明确指定字段的序列化方式:
// 方式一:使用knex.json const updateValue = { name: 'test name', service: knex.json({ domain: 'updated domain' }) } // 方式二:使用knex.raw const updateValue = { name: 'test name', service: knex.raw('?', [JSON.stringify({ domain: 'updated domain' })]) } knex('card').where('id', 1).update(updateValue).returning('*');
3. 修改表结构为JSON类型
如果你的SQLite版本在3.37.0及以上(支持JSON类型),可以将service列改为JSON类型,Knex会自动处理对象与JSON字符串的双向转换:
// 建表时指定JSON类型 knex.schema.createTable('card', table => { table.increments('id'); table.string('name'); table.json('service'); // 也可使用jsonb })
修改后,不管是insert还是update操作,Knex都会自动完成序列化,无需手动处理。
内容的提问来源于stack exchange,提问作者Michael Stowe
相关产品推荐
相关产品推荐

