如何访问 RowDataPacket 对象
How to access a RowDataPacket object
我目前正在使用 Node-webkit 开发桌面应用程序。在此过程中,我需要从本地 MySQL-数据库获取一些数据。
查询工作正常,但我不知道如何访问结果。我将它们全部存储在一个数组中,然后传递给一个函数。在控制台中,它们看起来像这样:
RowDataPacket {user_id: 101, ActionsPerformed: 20}
RowDataPacket {user_id: 102, ActionsPerformed: 110}
RowDataPacket {user_id: 104, ActionsPerformed: 3}
这里是查询结构:
var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
if (err)
alert("...");
else {
for (var i of rows)
ret.push(i);
}
doStuffwithTheResult(ret);
}
如何在 doStuffwithTheResult
函数中检索它?价值更重要,但如果我也能拿到钥匙,那就太好了。
原来它们是普通对象,你可以通过user_id
访问它们。
RowDataPacket实际上是创建对象的构造函数的名称,它看起来像这样new RowDataPacket(user_id, ...)
。你可以通过访问它的名字来检查 [0].constructor.name
如果结果是数组,则必须使用 [0].user_id
.
你尝试给出 JSON 没有 rowdatapacket 的代码:
var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
if (err)
alert("...");
else {
ret = JSON.stringify(rows);
}
doStuffwithTheResult(ret);
}
我最近也遇到了同样的问题,我在express项目中使用水线进行复杂查询时,使用SQL语句进行查询。
这是我的解决方案:首先将 return 值(RowDataPacket 对象)转换为字符串,然后将此字符串转换为 json 对象。
代码如下:
//select all user (查询全部用户)
find: function(req, res, next){
console.log("i am in user find list");
var sql="select * from tb_user";
req.models.tb_user.query(sql,function(err, results) {
console.log('>> results: ', results );
var string=JSON.stringify(results);
console.log('>> string: ', string );
var json = JSON.parse(string);
console.log('>> json: ', json);
console.log('>> user.name: ', json[0].name);
req.list = json;
next();
});
}
控制台如下:
>> results: [ RowDataPacket {
user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
name: 'wuwanyu',
psw: '123',
school: 'Northeastern university',
major: 'Communication engineering',
points: '10',
datems: '1450514441486',
createdAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),
updatedAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),
ID: 3,
phone: 2147483647 } ]
>> string: [{"user_id":"2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5","name":"wuwanyu","psw":"123","school":"Northeastern university","major":"Communication engineering","points":"10","datems":"1450514
441486","createdAt":"2015-12-19T08:42:31.000Z","updatedAt":"2015-12-19T08:42:31.000Z","ID":3,"phone":2147483647}]
>> json: [ { user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
name: 'wuwanyu',
psw: '123',
school: 'Northeastern university',
major: 'Communication engineering',
points: '10',
datems: '1450514441486',
createdAt: '2015-12-19T08:42:31.000Z',
updatedAt: '2015-12-19T08:42:31.000Z',
ID: 3,
phone: 2147483647 } ]
>> user.name: wuwanyu
您可以通过Object.assign(target, ...sources)将对象的所有可枚举自身属性复制到新对象:
trivial_object = Object.assign({}, non_trivial_object);
所以在你的场景中,改变一下就足够了
ret.push(i);
到
ret.push(Object.assign({}, i));
我找到了一个简单的方法
Object.prototype.parseSqlResult = function () {
return JSON.parse(JSON.stringify(this[0]))
}
在db层解析为
let users= await util.knex.raw('select * from user')
return users.parseSqlResult()
这会将 return 个元素作为正常的 JSON 数组。
使用Object.prototype
方法,JSON.parse(JSON.stringify(rows))
returns对象,使用Object.values()
提取值
const result = Object.values(JSON.parse(JSON.stringify(rows)));
用法:
result.forEach((v) => console.log(v));
摆脱 jan 对浅拷贝对象的回答,另一个使用 map 函数的干净实现,
此解决方案的高级操作:遍历所有行并将行复制为有效的 js 对象。
// function will be used on every row returned by the query
const objectifyRawPacket = row => ({...row});
// iterate over all items and convert the raw packet row -> js object
const convertedResponse = results.map(objectifyRawPacket);
我们利用了数组映射函数:它将遍历数组中的每个项目,将项目用作函数的输入,并将函数的输出插入到您正在分配的数组中。
更具体地说是 objectifyRawPacket 函数:每次调用它时都会从源数组中看到“{RawDataPacket}”。这些对象的行为很像普通对象——“...”(扩展)运算符在句点之后从数组中复制项目——本质上是将项目复制到它被调用的对象中。
函数上扩展运算符周围的括号对于隐式 return 来自箭头函数的对象是必需的。
更简单的方法:
.then( resp=> {
let resultFromDb= Object.values(resp)[0]
console.log(resultFromDb)
}
在我的示例中,我收到了一个对象作为响应。
当我使用 Object.values 时,我将 属性 的值作为响应,但是它位于一个数组中,使用 [0] 访问该数组的第一个索引,现在我有使用它的值我需要的地方。
我在尝试使用从存储过程返回的值时遇到了这个问题。
console.log(result[0]);
会输出“[RowDataPacket { datetime: '2019-11-15 16:37:05' } ]”。
我发现
console.log(results[0][0].datetime);
给了我想要的价值。
我真的不明白这有什么大不了的,我的意思是看看 运行 我的 sp 是 CALL ps_get_roles();
。
是的,我从 DB 和其他东西那里得到了一个丑陋的回应。这是哪个:
[
[
RowDataPacket {
id: 1,
role: 'Admin',
created_at: '2019-12-19 16:03:46'
},
RowDataPacket {
id: 2,
role: 'Recruiter',
created_at: '2019-12-19 16:03:46'
},
RowDataPacket {
id: 3,
role: 'Regular',
created_at: '2019-12-19 16:03:46'
}
],
OkPacket {
fieldCount: 0,
affectedRows: 0,
insertId: 0,
serverStatus: 35,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0
}
]
它是一个类似这样的数组:
rows[0] = [
RowDataPacket {/* them table rows*/ },
RowDataPacket { },
RowDataPacket { }
];
rows[1] = OkPacket {
/* them props */
}
但是如果我对客户端的 [0]
行进行 http response
索引,我会得到:
[
{"id":1,"role":"Admin","created_at":"2019-12-19 16:03:46"},
{"id":2,"role":"Recruiter","created_at":"2019-12-19 16:03:46"},
{"id":3,"role":"Regular","created_at":"2019-12-19 16:03:46"}
]
而且我不需要做 none 的事情
rows[0].map(row => {
return console.log("row: ", {...row});
});
输出是这样的:
row: { id: 1, role: 'Admin', created_at: '2019-12-19 16:03:46' }
row: { id: 2, role: 'Recruiter', created_at: '2019-12-19 16:03:46' }
row: { id: 3, role: 'Regular', created_at: '2019-12-19 16:03:46' }
所以你们都无缘无故地绊倒了。或者它也可能是我 运行ning 存储过程而不是常规查询的事实,查询和 sp 的响应是不一样的。
嗨,试试这个 100% 有效:
results=JSON.parse(JSON.stringify(results))
doStuffwithTheResult(results);
解决方案
就做:JSON.stringify(results)
db.query('select * from login',(err, results, fields)=>{
if(err){
console.log('error in fetching data')
}
var string=JSON.stringify(results);
console.log(string);
var json = JSON.parse(string);
// to get one value here is the option
console.log(json[0].name);
})
如果有人需要从多个查询中检索特定的 RowDataPacket 对象,就在这里。
开始之前
重要提示:确保在 mysql 连接中启用 multipleStatements
,如下所示:
// Connection to MySQL
var db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123',
database: 'TEST',
multipleStatements: true
});
多个查询
假设我们有多个查询 运行:
// All Queries are here
const lastCheckedQuery = `
-- Query 1
SELECT * FROM table1
;
-- Query 2
SELECT * FROM table2;
`
;
// Run the query
db.query(lastCheckedQuery, (error, result) => {
if(error) {
// Show error
return res.status(500).send("Unexpected database error");
}
如果我们console.log(result)
你会得到这样的输出:
[
[
RowDataPacket {
id: 1,
ColumnFromTable1: 'a',
}
],
[
RowDataPacket {
id: 1,
ColumnFromTable2: 'b',
}
]
]
两个表都会显示两个结果。
这是基本 Javascript 数组的用武之地 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
要从 table1
和名为 ColumnFromTable1
的列中获取数据,我们需要这样做
result[0][0].ColumnFromTable1 // Notice the double [0]
这给了我们 a
.
的结果
我遇到了类似的问题,解决方法如下:
const results = pool.query('sql sentence',[params]);
console.log((results[0])[0].name);
conn.query(sql, (err,res,fields) => {
let rawData = res;
let dataNormalized = {...rawData[0]};
})
//对象解构
这对我有用,希望对你有帮助。
我认为这是复制对象最简单的方法。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
我目前正在使用 Node-webkit 开发桌面应用程序。在此过程中,我需要从本地 MySQL-数据库获取一些数据。
查询工作正常,但我不知道如何访问结果。我将它们全部存储在一个数组中,然后传递给一个函数。在控制台中,它们看起来像这样:
RowDataPacket {user_id: 101, ActionsPerformed: 20}
RowDataPacket {user_id: 102, ActionsPerformed: 110}
RowDataPacket {user_id: 104, ActionsPerformed: 3}
这里是查询结构:
var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
if (err)
alert("...");
else {
for (var i of rows)
ret.push(i);
}
doStuffwithTheResult(ret);
}
如何在 doStuffwithTheResult
函数中检索它?价值更重要,但如果我也能拿到钥匙,那就太好了。
原来它们是普通对象,你可以通过user_id
访问它们。
RowDataPacket实际上是创建对象的构造函数的名称,它看起来像这样new RowDataPacket(user_id, ...)
。你可以通过访问它的名字来检查 [0].constructor.name
如果结果是数组,则必须使用 [0].user_id
.
你尝试给出 JSON 没有 rowdatapacket 的代码:
var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
if (err)
alert("...");
else {
ret = JSON.stringify(rows);
}
doStuffwithTheResult(ret);
}
我最近也遇到了同样的问题,我在express项目中使用水线进行复杂查询时,使用SQL语句进行查询。
这是我的解决方案:首先将 return 值(RowDataPacket 对象)转换为字符串,然后将此字符串转换为 json 对象。
代码如下:
//select all user (查询全部用户)
find: function(req, res, next){
console.log("i am in user find list");
var sql="select * from tb_user";
req.models.tb_user.query(sql,function(err, results) {
console.log('>> results: ', results );
var string=JSON.stringify(results);
console.log('>> string: ', string );
var json = JSON.parse(string);
console.log('>> json: ', json);
console.log('>> user.name: ', json[0].name);
req.list = json;
next();
});
}
控制台如下:
>> results: [ RowDataPacket {
user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
name: 'wuwanyu',
psw: '123',
school: 'Northeastern university',
major: 'Communication engineering',
points: '10',
datems: '1450514441486',
createdAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),
updatedAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),
ID: 3,
phone: 2147483647 } ]
>> string: [{"user_id":"2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5","name":"wuwanyu","psw":"123","school":"Northeastern university","major":"Communication engineering","points":"10","datems":"1450514
441486","createdAt":"2015-12-19T08:42:31.000Z","updatedAt":"2015-12-19T08:42:31.000Z","ID":3,"phone":2147483647}]
>> json: [ { user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
name: 'wuwanyu',
psw: '123',
school: 'Northeastern university',
major: 'Communication engineering',
points: '10',
datems: '1450514441486',
createdAt: '2015-12-19T08:42:31.000Z',
updatedAt: '2015-12-19T08:42:31.000Z',
ID: 3,
phone: 2147483647 } ]
>> user.name: wuwanyu
您可以通过Object.assign(target, ...sources)将对象的所有可枚举自身属性复制到新对象:
trivial_object = Object.assign({}, non_trivial_object);
所以在你的场景中,改变一下就足够了
ret.push(i);
到
ret.push(Object.assign({}, i));
我找到了一个简单的方法
Object.prototype.parseSqlResult = function () {
return JSON.parse(JSON.stringify(this[0]))
}
在db层解析为
let users= await util.knex.raw('select * from user')
return users.parseSqlResult()
这会将 return 个元素作为正常的 JSON 数组。
使用Object.prototype
方法,JSON.parse(JSON.stringify(rows))
returns对象,使用Object.values()
const result = Object.values(JSON.parse(JSON.stringify(rows)));
用法:
result.forEach((v) => console.log(v));
摆脱 jan 对浅拷贝对象的回答,另一个使用 map 函数的干净实现,
此解决方案的高级操作:遍历所有行并将行复制为有效的 js 对象。
// function will be used on every row returned by the query
const objectifyRawPacket = row => ({...row});
// iterate over all items and convert the raw packet row -> js object
const convertedResponse = results.map(objectifyRawPacket);
我们利用了数组映射函数:它将遍历数组中的每个项目,将项目用作函数的输入,并将函数的输出插入到您正在分配的数组中。
更具体地说是 objectifyRawPacket 函数:每次调用它时都会从源数组中看到“{RawDataPacket}”。这些对象的行为很像普通对象——“...”(扩展)运算符在句点之后从数组中复制项目——本质上是将项目复制到它被调用的对象中。
函数上扩展运算符周围的括号对于隐式 return 来自箭头函数的对象是必需的。
更简单的方法:
.then( resp=> {
let resultFromDb= Object.values(resp)[0]
console.log(resultFromDb)
}
在我的示例中,我收到了一个对象作为响应。 当我使用 Object.values 时,我将 属性 的值作为响应,但是它位于一个数组中,使用 [0] 访问该数组的第一个索引,现在我有使用它的值我需要的地方。
我在尝试使用从存储过程返回的值时遇到了这个问题。
console.log(result[0]);
会输出“[RowDataPacket { datetime: '2019-11-15 16:37:05' } ]”。
我发现
console.log(results[0][0].datetime);
给了我想要的价值。
我真的不明白这有什么大不了的,我的意思是看看 运行 我的 sp 是 CALL ps_get_roles();
。
是的,我从 DB 和其他东西那里得到了一个丑陋的回应。这是哪个:
[
[
RowDataPacket {
id: 1,
role: 'Admin',
created_at: '2019-12-19 16:03:46'
},
RowDataPacket {
id: 2,
role: 'Recruiter',
created_at: '2019-12-19 16:03:46'
},
RowDataPacket {
id: 3,
role: 'Regular',
created_at: '2019-12-19 16:03:46'
}
],
OkPacket {
fieldCount: 0,
affectedRows: 0,
insertId: 0,
serverStatus: 35,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0
}
]
它是一个类似这样的数组:
rows[0] = [
RowDataPacket {/* them table rows*/ },
RowDataPacket { },
RowDataPacket { }
];
rows[1] = OkPacket {
/* them props */
}
但是如果我对客户端的 [0]
行进行 http response
索引,我会得到:
[
{"id":1,"role":"Admin","created_at":"2019-12-19 16:03:46"},
{"id":2,"role":"Recruiter","created_at":"2019-12-19 16:03:46"},
{"id":3,"role":"Regular","created_at":"2019-12-19 16:03:46"}
]
而且我不需要做 none 的事情
rows[0].map(row => {
return console.log("row: ", {...row});
});
输出是这样的:
row: { id: 1, role: 'Admin', created_at: '2019-12-19 16:03:46' }
row: { id: 2, role: 'Recruiter', created_at: '2019-12-19 16:03:46' }
row: { id: 3, role: 'Regular', created_at: '2019-12-19 16:03:46' }
所以你们都无缘无故地绊倒了。或者它也可能是我 运行ning 存储过程而不是常规查询的事实,查询和 sp 的响应是不一样的。
嗨,试试这个 100% 有效:
results=JSON.parse(JSON.stringify(results))
doStuffwithTheResult(results);
解决方案
就做:JSON.stringify(results)
db.query('select * from login',(err, results, fields)=>{
if(err){
console.log('error in fetching data')
}
var string=JSON.stringify(results);
console.log(string);
var json = JSON.parse(string);
// to get one value here is the option
console.log(json[0].name);
})
如果有人需要从多个查询中检索特定的 RowDataPacket 对象,就在这里。
开始之前
重要提示:确保在 mysql 连接中启用 multipleStatements
,如下所示:
// Connection to MySQL
var db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123',
database: 'TEST',
multipleStatements: true
});
多个查询
假设我们有多个查询 运行:
// All Queries are here
const lastCheckedQuery = `
-- Query 1
SELECT * FROM table1
;
-- Query 2
SELECT * FROM table2;
`
;
// Run the query
db.query(lastCheckedQuery, (error, result) => {
if(error) {
// Show error
return res.status(500).send("Unexpected database error");
}
如果我们console.log(result)
你会得到这样的输出:
[
[
RowDataPacket {
id: 1,
ColumnFromTable1: 'a',
}
],
[
RowDataPacket {
id: 1,
ColumnFromTable2: 'b',
}
]
]
两个表都会显示两个结果。
这是基本 Javascript 数组的用武之地 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
要从 table1
和名为 ColumnFromTable1
的列中获取数据,我们需要这样做
result[0][0].ColumnFromTable1 // Notice the double [0]
这给了我们 a
.
我遇到了类似的问题,解决方法如下:
const results = pool.query('sql sentence',[params]);
console.log((results[0])[0].name);
conn.query(sql, (err,res,fields) => {
let rawData = res;
let dataNormalized = {...rawData[0]};
})
//对象解构
这对我有用,希望对你有帮助。
我认为这是复制对象最简单的方法。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment