2016-04-13 7 views
2

Zum Beispiel zur Abfrage ich der Benutzer Informationen erhalten möchten, E-Mails und die Rollen von db und ein Objekt zu erstellen, wie:beste Weg, um eine viele zu viele Beziehung mit pg-Versprechen

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

Es gibt drei Tabellen I müssen abfragen:

  • Users Tabelle hat id, firstname, lastname.
  • Emails Tabelle hat type, email, user_id.
  • Roles Tabelle hat role, title, user_id.

Basierend auf den pg-promise ‚s Wiki bin ich fast sicher, dass es getan werden muss Tasks verwenden, aber nicht sicher, wie man sich ketten würde.

UPDATE In meinem eigentlichen Projekt musste ich ein Produkt einfügen und die generierte ID verwenden, um Attribute einzufügen. Hinzufügen meinen Code hier, falls Sie eine ähnliche Situation:

//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]; 
      }); 
    }); 
} 
+0

Sie Kette Abfragen, wenn die Parameter einer Abfrage das Ergebnis der die vorherige Abfrage sind, die ist in Ihrem Beispiel nicht der Fall. Ihr Beispiel hat keine Abhängigkeit zwischen Abfrageergebnissen. Keine Verkettung ist erforderlich. –

+0

@ vitaly-t, Ja, ich habe bei der Frage einen Fehler gemacht. Mein tatsächlicher Fall ist, dass ich die E-Mail habe und die user_id zuerst aus der E-Mail-Tabelle holen muss. – Parham

+0

@ vitaly-t, Stimmt alles mit dem Update, das ich gerade hinzugefügt habe, Es fügt das Produkt hinzu und gibt die ID zurück, aber mit Debugger bekomme ich einen asynchronen Fehler 'Loose Anfrage außerhalb einer abgelaufenen Verbindung.' bei pg-promise /lib/query.js Zeile 183 'reject (errMsg);' – Parham

Antwort

1

Was Sie beschreiben nicht ein Many-to-Many-Beziehung ist, ist es 2 One-To-Many Beziehungen.

Basierend auf den pg-promise ‚s Wiki bin ich fast sicher, dass es getan werden muss Tasks verwenden, aber nicht sicher, wie man sich ketten würde.

In Ihrem Beispiel muss nichts verkettet werden. One Chains verspricht, wenn das Ergebnis eines als Kriterium für das nächste verwendet werden muss, denn so funktionieren Versprechungen, nicht nur Anfragen.

Dadurch können Sie alle 3 Abfragen parallel als Batch ausführen.

Das folgende Beispiel pg-promise mit Bluebird als Versprechen Bibliothek verwendet:

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; 
     }) 
} 

Anwendungsbeispiel:

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

Danke!Könnten Sie mich wissen lassen, wie es geht, wenn ich stattdessen den Benutzernamen habe und zuerst die Benutzertabelle abfragen muss, um die ID heraus zu bekommen? – Parham

+0

@Parham ist das irgendeine Hilfe? - https://github.com/vitaly-t/pg-promise/blob/master/examples/select-insert.md –

+0

ja, ich denke, das sollte funktionieren. Vielen Dank. Ich werde es versuchen, sobald ich eine Chance habe und werde updaten. – Parham