使用pg-promise查询多对多关系的最佳方法

例如,我想从数据库中获取用户信息,电子邮件和angular色,并创build一个对象:

{ "id": 1, "firstname": "John", "lastname": "Johnny", "emails": [ { "type": "work", "email": "work@work.com" }, { "type": "personal", "email": "personal@personal.com" } ], "roles": [ { "role": "ADM", "title": "Admin" }, { "role": "PUB", "title": "Publisher" } ] } 

有三个表我需要查询:

  • Users表有idfirstnamelastname
  • Emails表具有typeemail ,用户user_id
  • Roles表有roletitleuser_id

基于pg-promise的维基,我几乎可以肯定,它必须使用任务完成,但不知道如何链接它们。

更新在我的实际项目中,我不得不插入一个产品,并使用生成的ID来插入属性。 如果您遇到类似情况,请在此处添加我的代码:

 //Insert a new product with attribites as key value pairs post_product_with_attr: function(args) { return db.task(function(t) { return t.one(sql.post_new_product, args) .then(function(dt) { var queries = []; Object.keys(args).forEach(function(key) { queries.push(t.one(sql.post_attr_one, { Id: dt.id, key: key, value: args[key] })); }); return queries.length ? t.batch(queries) : [dt]; }); }); } 

你所描述的不是多对多的关系,而是两对一的关系。

基于pg-promise的维基,我几乎可以肯定,它必须使用任务完成,但不知道如何链接它们。

在你的例子中,不需要链接任何东西。 当一个链的结果需要被用作下一个链的标准时,一个链承诺,因为承诺是如何工作的,而不仅仅是查询。

因此,可以并行执行所有3个查询,作为批处理。

下面的例子使用蓝鸟的 pg-promise作为承诺库:

 function getUserInfo(userId) { return db.task(t=>t.batch([ t.one('SELECT id, firstname, lastname FROM Users WHERE id = $1', userId), t.any('SELECT type, email FROM Emails WHERE user_id = $1', userId), t.any('SELECT role, title FROM Roles WHERE user_id = $1', userId) ])) .spread((user, emails, roles)=> { user.emails = emails; user.roles = roles; return user; }) } 

用法示例:

 getUserInfo(123) .then(info=> { // info = object as described in the question; }) .catch(error=> { // error; });