2 votes

pg-promise task and map avec plusieurs requêtes imbriquées de même niveau

J'utilise node et pg-promise pour créer une API de base et j'ai un problème pour interroger toutes les données d'un utilisateur particulier. Voici à quoi devraient ressembler les données renvoyées. L'adresse, le numéro de téléphone et les compétences sont tous dans des tables séparées. Je n'ai aucun problème pour récupérer les adresses ou les numéros de téléphone, mais je n'arrive pas à obtenir les compétences. Je ne sais pas vraiment comment faire pour avoir plusieurs requêtes après la requête principale qui permet à l'utilisateur d'obtenir tous ces autres champs. Veuillez consulter le code ci-joint à titre de référence et je serai heureux de répondre à vos questions.


{
"user_id": 1,
"first_name": "Eugene",
"last_name": "Hanson",
"display_name": "Eugene Hanson",
"email": "ehanson0@typepad.com",
"hash": "88a6aa27235d2e39dd9cb854cc246487147050f265578a3e1aee35be5db218ef",
"privilege_id": 14,
"seniority": 1,
"birthday": "19-11-1940 00:00:00.0",
"shift_count_total": 587,
"shift_count_year": 62,
"address_id": 1,
"street": "92 Schmedeman Lane",
"city": "Fort Smith",
"state": "AR",
"zip": 72905,
"phone_numbers": [
  {
    "phone_number": "62-(705)636-2916",
    "name": "PRIMARY"
  }
],
"skills": [
    "Head Audio",
    "Head Video",
    "Head Electrician",
    "Carpenter",
    "rigger"
    ]
}

    function getAllUsers() {
    // console.time("answer time")
    var deferred = Q.defer();
    db.task(t => {
        return t.map('SELECT * \
                        FROM users \
                        JOIN addresses \
                        ON users.address_id = addresses.address_id',[], user => {
            var user_id = user.user_id;
            // console.log(user_id)
            console.time("answer time")
            return t.manyOrNone('SELECT phone_numbers.phone_number, phone_types.name \
                                    FROM users \
                                    JOIN users_phone_numbers \
                                    ON users.user_id = users_phone_numbers.user_id \
                                    JOIN phone_numbers \
                                    ON users_phone_numbers.phone_id = phone_numbers.phone_id \
                                    JOIN phone_types \
                                    ON phone_numbers.phone_type_id = phone_types.phone_type_id \
                                    WHERE users.user_id = $1', user.user_id)
                                    .then(phone_numbers=> {
                                        // logger.log('info', phone_numbers)
                                        user.phone_numbers = phone_numbers;
                                        return user;
                                    })
        }).then(t.batch);
    })
    .then(data => {
        // console.log(data)
        console.timeEnd("answer time");
        var response = {code: "200", 
                        message: "", 
                        payload: data};
        deferred.resolve(response);
    })
    .catch(error => {
    var response = {code: error.code, 
                    message: error.message, 
                    payload: ""};
    logger.log('error', error)
    deferred.reject(response)
});

1voto

user1102051 Points 152

Je suis l'auteur de pg-promesse .


Une version simplifiée de votre fonction serait :

function getAllUsers() {
    return db.task(t => {
        return t.map('SELECT * FROM users', [], user => {
            return t.batch([
                t.any('SELECT * FROM phones'), // plus formatting params
                t.any('SELECT * FROM skills'), // plus formatting params
            ])
                .then(data => {
                    user.phones = data[0];
                    user.skills = data[1];
                    return user;
                });
        }).then(t.batch);
    });
}

getAllUsers()
    .then(data => {
        // data tree
    })
    .catch(error => {
        // error
    });

Et si vous utilisez oiseau bleu comme bibliothèque de promesses, alors vous pouvez remplacer ce code :

.then(data => {
    user.phones = data[0];
    user.skills = data[1];
    return user;
});

avec celui-ci :

.spread((phones, skills) => {
    user.phones = phones;
    user.skills = skills;
    return user;
});

Et n'utilisez pas des choses comme var deferred = Q.defer(); il n'est pas nécessaire à cet endroit. La bibliothèque est déjà basée sur les promesses.

Pour une alternative performante, voir : obtenir une table JOIN comme tableau de résultats avec PostgreSQL/NodeJS .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X