2016-04-13 2 views
2

Например, я хочу, чтобы получить данные пользователя, сообщения электронной почты, и это роли из БД и создать объект, как:Лучший способ запросить многие ко многим, используя PG-обещание

{ 
    "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" 
    } 
    ] 
} 

Есть три таблицы I необходимо запросить:

  • Users таблица имеет id, firstname, lastname.
  • Emails стол имеет type, email, user_id.
  • Roles стол имеет role, title, user_id.

на основе вики pg-promise «s Я почти уверен, что это должно быть сделано с помощью Tasks, но не уверен, как вы бы приковать их.

UPDATE В моем фактическом проекте мне пришлось вставить продукт и использовать сгенерированный идентификатор для вставки атрибутов. Добавление моего кода здесь в случае, если у вас есть подобная ситуация:

//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

Вы цепочка запросы, когда параметры одного запроса являются результатом из предыдущего запроса, который в вашем примере это не так. В вашем примере нет зависимости между результатами запроса. Не требуется цепочки. –

+0

@ vitaly-t, Да, я ошибся в вопросе. Мое фактическое дело в том, что у меня есть электронное письмо, и сначала нужно получить user_id из таблицы электронной почты. – Parham

+0

@ vitaly-t, Что-то не в порядке с обновлением, которое я только что добавил, Он добавляет продукт и возвращает идентификатор, но использует отладчик. Я получаю асинхронную ошибку «Свободный запрос за пределами истекшего соединения». Pg-prom /lib/query.js строка 183 'reject (errMsg);' – Parham

ответ

1

То, что вы описываете, это не многие-ко-многим, это 2 Один-ко-многим.

на основе вики pg-promise «s Я почти уверен, что это должно быть сделано с помощью Tasks, но не уверен, как вы бы приковать их.

В вашем примере нет необходимости ничего цепочки. Одна цепочка обещает, когда результат нужно использовать в качестве критериев для следующего, потому что это то, как работают обещания, а не только запросы.

Из-за этого вы можете выполнять все 3 запроса параллельно, как пакет.

В приведенном ниже примере используется pg-promise с Bluebird как библиотека обещания:

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

Спасибо!Не могли бы вы дать мне знать, как это сделать, если у меня есть имя пользователя вместо этого, и сначала нужно запросить таблицу пользователя, чтобы получить id из него? – Parham

+0

@ Parham - это любая помощь? - https://github.com/vitaly-t/pg-promise/blob/master/examples/select-insert.md –

+0

да, я думаю, что это должно сработать. Благодарю. Я попробую, как только у меня появится шанс и будет обновляться. – Parham