gpt4 book ai didi

node.js - 使用 pg-promise 的嵌套事务

转载 作者:行者123 更新时间:2023-11-29 13:21:07 25 4
gpt4 key购买 nike

我正在使用 NodeJS、PostgreSQL 和惊人的 pg-promise图书馆。就我而言,我想执行三个主要查询:

  1. 在“推文”表中插入一条推文。
  2. 如果推文中有主题标签,将它们插入到另一个表“hashtags”中
  3. 他们在第三个表“hashtagmap”(多对多关系表)中链接推文和主题标签

这是请求正文 (JSON) 的示例:

{
"id":"12344444",
"created_at":"1999-01-08 04:05:06 -8:00",
"userid":"@postman",
"tweet":"This is the first test from postman!",
"coordinates":"",
"favorite_count":"0",
"retweet_count":"2",
"hashtags":{
"0":{
"name":"test",
"relevancetraffic":"f",
"relevancedisaster":"f"
},
"1":{
"name":"postman",
"relevancetraffic":"f",
"relevancedisaster":"f"
},
"2":{
"name":"bestApp",
"relevancetraffic":"f",
"relevancedisaster":"f"
}
}

除主题标签外,上述所有字段都应包含在表“tweets”中,而主题标签又应包含在表“hashtags”中。

这是我使用的代码,基于来自 NodeJS 模块内的 pg-promise 文档的嵌套事务。我想我需要嵌套事务,因为我需要知道 tweet_idhashtag_id 以便在 hashtagmap 表中链接它们。

// Columns
var tweetCols = ['id','created_at','userid','tweet','coordinates','favorite_count','retweet_count'];

var hashtagCols = ['name','relevancetraffic','relevancedisaster'];

//pgp Column Sets
var cs_tweets = new pgp.helpers.ColumnSet(tweetCols, {table: 'tweets'});

var cs_hashtags = new pgp.helpers.ColumnSet(hashtagCols, {table:'hashtags'});
return{
// Transactions
add: body =>
rep.tx(t => {
return t.one(pgp.helpers.insert(body,cs_tweets)+" ON CONFLICT(id) DO UPDATE SET coordinates = "+body.coordinates+" RETURNING id")
.then(tweet => {
var queries = [];
for(var i = 0; i < body.hashtags.length; i++){
queries.push(
t.tx(t1 => {
return t1.one(pgp.helpers.insert(body.hashtags[i],cs_hashtags) + "ON CONFLICT(name) DO UPDATE SET fool ='f' RETURNING id")
.then(hash =>{
t1.tx(t2 =>{
return t2.none("INSERT INTO hashtagmap(tweetid,hashtagid) VALUES("+tweet.id+","+hash.id+") ON CONFLICT DO NOTHING");
});
});
}));
}
return t.batch(queries);
});
})
}

问题出在这段代码上,我能够成功插入推文,但之后什么也没有发生。我无法插入主题标签,也无法将主题标签链接到推文。

抱歉,我是编码新手,所以我想我不明白如何正确地从交易中返回以及如何执行这个简单的任务。希望你能帮我。

提前谢谢你。

最佳答案

改进 Jean Phelippe 自己的回答:

// Columns
var tweetCols = ['id', 'created_at', 'userid', 'tweet', 'coordinates', 'favorite_count', 'retweet_count'];

var hashtagCols = ['name', 'relevancetraffic', 'relevancedisaster'];

//pgp Column Sets
var cs_tweets = new pgp.helpers.ColumnSet(tweetCols, {table: 'tweets'});

var cs_hashtags = new pgp.helpers.ColumnSet(hashtagCols, {table: 'hashtags'});

return {
/* Tweets */
// Add a new tweet and update the corresponding hash tags
add: body =>
db.tx(t => {
return t.one(pgp.helpers.insert(body, cs_tweets) + ' ON CONFLICT(id) DO UPDATE SET coordinates = ' + body.coordinates + ' RETURNING id')
.then(tweet => {
var queries = Object.keys(body.hashtags).map((_, idx) => {
return t.one(pgp.helpers.insert(body.hashtags[i], cs_hashtags) + 'ON CONFLICT(name) DO UPDATE SET fool = $1 RETURNING id', 'f')
.then(hash => {
return t.none('INSERT INTO hashtagmap(tweetid, hashtagid) VALUES($1, $2) ON CONFLICT DO NOTHING', [+tweet.id, +hash.id]);
});
});
return t.batch(queries);
});
})
.then(data => {
// transaction was committed;
// data = [null, null,...] as per t.none('INSERT INTO hashtagmap...
})
.catch(error => {
// transaction rolled back
})
},

注意事项:

  • 根据我之前的笔记,您必须链接所有查询,否则您最终会得到松散的 promise
  • 远离嵌套事务,除非您确切了解它们在 PostgreSQL 中的工作方式(read this,特别是限制部分)。
  • 避免手动查询格式化,这是不安全的,始终依赖图书馆的查询格式化。
  • 除非您将交易结果传递到其他地方,否则您至少应该提供 .catch 处理程序。

附言对于像 +tweet.id 这样的语法,它与 parseInt(tweet.id) 相同,只是更短,以防它们是字符串 ;)

关于node.js - 使用 pg-promise 的嵌套事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41662027/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com