在NodeJS中,如何使用node-postgres模块将JSON对象保存为文本?

3

最终我从支持JSON数据类型的PostgreSQL 9.1升级到PostgreSQL 9.3。然后相同的代码可以正常运行。

但是我认为,如果有人知道如何做到我最初想要做的事情,那就更好了,我仍然想知道。


环境
node v0.10.28
pg v3.3.0
postgresql 9.1

我得到了这个插入查询。

INSERT INTO sessions(sid, user_id, session_object) VALUES ('id1', 1, '{"id":"fX2HkXYLclB","data": testing"}') RETURNING session_id

当我从pgAdmin(或命令行)进行测试时,它能够正常工作,但是当我的应用程序尝试从pg.client.query运行它时,它会将对象转换为字符串并保存为“[object object]”。以下是Node.js代码:

var session = {"id":"fX2HkXYLclB","data": "testing"};
var sql = 'INSERT INTO sessions(sid, user_id, session_object) VALUES (\'id1\', ' +
          ' 1, \''+JSON.stringify(session)+'\' ) RETURNING session_id';
console.log(sql);
client.query(sql, function(err, info) {
  if(err) {
  return addSessionCB(err, null);
  }
  return addSessionCB(null, info.rows[0].session_id);
});

运行应用程序并在pg_admin上手动测试查询后,表格显示了这两个结果。

 session_id |     sid     | user_id |            session_object             | active 
------------+-------------+---------+---------------------------------------+---------
          1 | fX2HkXYLclB |       1 | [object Object]                       | t
          2 | fX2HkXYLclB |       1 | {"id":"fX2HkXYLclB","data": "testing"}| t
(2 filas)

所以,问题是我在使用pg.query时哪里出错了?
为了易读性,以下是简化后的代码。
function addSession(session, addSessionCB) {
  log.log('debug', '[PSQL]Add new session on DB. \nsession: '+ session.id +
    '\nuser:'+ session.data.user);
  function executeAddSessionQuery(user_id){
    var sql = 'INSERT INTO sessions(sid, user_id, session_object) VALUES (\'' +
      session.id + '\', '+user_id+', \''+JSON.stringify(session)+'\' ) ' +
      'RETURNING session_id';
    log.log('debug', '[PSQL]Adding session: '+session.id+' for user_id: '+
      user_id+'\nSQL: '+sql);
    client.query(sql, function(err, info) {
      if(err) {
        log.log('debug', '[PSQL]Error adding new session. \n'+err);
        return addSessionCB(err, null);
      }
      return addSessionCB(null, info.rows[0].session_id);
    });
  };
//to save session we need to know user id
  getUserByName({name: session.data.user},
    function getUserByNameCB(err, user_result){

      if(err || !user_result){
        //if error or not result we try to save new user
        log.log('debug', '[PSQL]Associated user not found. Creating a new ' +
          'user entry. ');
        addUser({name: session.data.user},
          function addUserCB(err, newUserID){
            if(err){
              log.log('warn', '[PSQL]Session user didn\'t exists and cannot be ' +
                'added to DB');
              return addSessionCB(err, null);
            }
            executeAddSessionQuery(newUserID);
        });
      } else {
        //if the user exist we use his id.
        executeAddSessionQuery(user_result.user_id);
      }
  });
}

这听起来像是一个 obj.toString() 的问题。你没有在任何对象上使用 toString(),是吗?我在这里没有看到它,但除此之外,你的代码应该可以工作。 - glortho
不需要。这里的代码已经简化了,但与原始版本非常相似。JSON.stringify(session)给我一个字符串,所以我不需要为了什么而使用session.toString() - darofar
你能分享原始代码吗? - glortho
你明白了,希望能有所帮助。 - darofar
1个回答

4

Node.js的PostgreSQL模块有另一种形式的查询,第二个参数是对象数组。所以在你的情况下:

var sql = 'INSERT INTO sessions(sid,user_id,session_object) VALUES ($1,$2,$3) RETURNING session_id';
var values = [id1,1,JSON.stringify(session)];

然后跟进此操作。
client.query(sql,values,function(err,info) {
...

这也有一个额外的好处,可以防止SQL注入攻击。


是的...我也尝试过那个,但仍然得到了相同的结果。 - darofar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接