Knex查询Sqlite3返回JSON为字符串的问题咨询
解决SQLite+Knex查询返回JSON字符串而非对象的问题
方法1:利用SQLite内置json()函数直接返回JSON对象
SQLite 3.38.0及以上版本支持json()函数,可将JSON字符串转换为SQLite原生JSON类型,Knex会自动将其映射为JavaScript对象。修改你的查询语句,将主查询中的child.data替换为db.raw('json(child.data) as data'):
db .select('parent.id', 'parent.name', db.raw('json(child.data) as data')) .from('parent') .leftJoin( db .select("parentid", db.raw("json_group_array( json_object ( 'id', id, 'temp', temp )) as data")) .from("child") .groupBy('parentid') .as('child') , function(){ this.on('parent.id','=', 'child.parentid') } ) .orderBy('parent.id')
执行后返回的data字段直接就是JavaScript数组对象,无需额外解析。
方法2:给单个查询添加postProcessResponse钩子
如果你的SQLite版本较低不支持json()函数,可以在当前查询链中添加postProcessResponse,让Knex在处理结果时自动解析data字段:
db .select('parent.id', 'parent.name', 'child.data') .from('parent') .leftJoin( db .select("parentid", db.raw("json_group_array( json_object ( 'id', id, 'temp', temp )) as data")) .from("child") .groupBy('parentid') .as('child') , function(){ this.on('parent.id','=', 'child.parentid') } ) .orderBy('parent.id') .postProcessResponse(results => { return results.map(item => { if (item.data) { try { item.data = JSON.parse(item.data); } catch (err) { // 解析失败时保留原字符串,避免报错 } } return item; }); })
这个操作属于查询本身的配置,无需在API层单独写循环逻辑。
方法3:全局配置Knex的结果处理钩子
如果多个查询都需要处理JSON字符串转对象,可以在创建Knex实例时全局配置postProcessResponse,实现所有查询自动解析指定字段:
const knex = require('knex')({ client: 'sqlite3', connection: { filename: './your-db.sqlite' }, postProcessResponse: (results, queryContext) => { if (Array.isArray(results)) { return results.map(item => { // 针对data字段做自动解析 if (item.data && typeof item.data === 'string') { try { item.data = JSON.parse(item.data); } catch (err) {} } return item; }); } // 处理单条结果的情况 if (results.data && typeof results.data === 'string') { try { results.data = JSON.parse(results.data); } catch (err) {} } return results; } });
这样所有查询返回的data字段都会被自动尝试解析为对象,无需重复编写解析逻辑。
内容的提问来源于stack exchange,提问作者j4rey
相关产品推荐
相关产品推荐

