A resposta imediata para sua pergunta é usar um procedimento armazenado para fazer um upsert.
http://www.postgresql .org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
Algo assim funciona bem com o módulo 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
});
É claro que isso pressupõe que você esteja usando algum tipo de objeto de modelo que tenha todos os valores necessários, mesmo que eles não estejam mudando. Você tem que passá-los todos para o upsert. Se você está preso fazendo isso da maneira que você mostrou aqui, você provavelmente deve verificar o objeto de erro real após a atualização para determinar se ele falhou porque a linha já está lá, ou por algum outro motivo (que é um erro de banco de dados real que precisa ser tratado).
Então você tem que lidar com a possível condição de corrida entre o momento em que sua atualização falhou e o momento em que sua inserção passa. Se alguma outra função tentar inserir com o mesmo id, você terá um problema. As transações são boas para isso. Isso é tudo que eu tenho agora. Espero que ajude.