使用 node.js 在 Postgres 中更新插入

jri*_*iro 5 postgresql upsert node.js pg

我正在尝试使用带有 pg 扩展名(版本 0.5.4)的 node.js 在 postgres 数据库中进行插入或更新。

到目前为止,我有这个代码:(...)

client.query({
            text: "update users set is_active = 0, ip = $1 where id=$2",
            values: [ip,id]
        }, function(u_err, u_result){
            debug(socket_id,"update query result: ",u_result);
                debug(socket_id,"update query error: ",u_err);

                    date_now = new Date();
            var month = date_now.getMonth() + 1;

            if(!u_err){

                client.query({
                    text: 'insert into users (id,first_name,last_name,is_active,ip,date_joined) values' +
                    '($1,$2,$3,$4,$5,$6)',
                    values: [
                            result.id, 
                            result.first_name,
                            result.last_name,
                            1,
                            ip,
                            date_now.getFullYear() + "-" + month + "-" + date_now.getDate() + " " + date_now.getHours() + ":" + date_now.getMinutes() + ":" + date_now.getSeconds()
                            ]
                }, function(i_err, i_result){
                    debug(socket_id,"insert query result: ",i_result);
                    debug(socket_id,"insert query error: ",i_err);
                });
            }
        });
Run Code Online (Sandbox Code Playgroud)

问题是,虽然两个查询都有效,但问题总是同时运行,而不是仅在更新失败时运行插入函数。

代码输出中的调试功能类似于:

更新

Object { type="update query result: ", debug_value={...}}
home (linha 56)
Object { type="update query error: ", debug_value=null}
home (linha 56)
Object { type="insert query result: "}
home (linha 56)
Object { type="insert query error: ", debug_value={...}}
Run Code Online (Sandbox Code Playgroud)

插入

Object { type="update query result: ", debug_value={...}}
home (linha 56)
Object { type="update query error: ", debug_value=null}
home (linha 56)
Object { type="insert query result: ", debug_value={...}}
home (linha 56)
Object { type="insert query error: ", debug_value=null}
Run Code Online (Sandbox Code Playgroud)

** 编辑 **

来自 node-postgres 开发人员的回答:

可以检索受插入和更新影响的行数。它没有在本机绑定中完全实现,但在纯 javascript 版本中确实有效。我将在接下来的一两周内解决这个问题。同时使用纯 javascript 版本并在这里查看:

https://github.com/brianc/node-postgres/blob/master/test/integration/client/result-metadata-tests.js

** 结束编辑 **

任何人都可以帮忙吗?

Mar*_*rco 2

您问题的直接答案是使用存储过程进行更新插入。

http://www.postgresql.org/docs/current/static/plpgsql-control-structs.html#PLPGSQL-UPSERT-EXAMPLE

像这样的东西与 pg 模块一起工作得很好。

client.query({
  text: "SELECT upsert($1, $2, $3, $4, $5, $6)"
  values: [ obj.id, 
            obj.first_name,
            obj.last_name,
            1,
            ip,
            date_now.getFullYear() + "-" + month + "-" + date_now.getDate() + " " + date_now.getHours() + ":" + date_now.getMinutes() + ":" + date_now.getSeconds()
          ]
}, function(u_err, u_result){
  if(err) // this is a real error, handle it

  // otherwise your data is updated or inserted properly
});
Run Code Online (Sandbox Code Playgroud)

当然,这假设您正在使用某种具有您需要的所有值的模型对象,即使它们没有改变。您必须将它们全部传递到 upsert 中。如果您坚持按照此处所示的方式进行操作,您可能应该在更新后检查实际的错误对象,以确定它是否因该行已经存在而失败,或者由于某些其他原因(这是真正的数据库错误)需要处理)。

然后,您必须处理更新失败的时间和插入完成的时间之间潜在的竞争条件。如果其他函数尝试使用相同的 id 进行插入,则会出现问题。交易对此有好处。这就是我现在所得到的。希望能帮助到你。