web-dev-qa-db-fra.com

Sequelize - Comment puis-je renvoyer uniquement les objets JSON des résultats de la base de données?

Je souhaite donc que les résultats de la base de données soient renvoyés et rien d'autre. Pour le moment, je reçois un gros morceau de données JSON (comme ci-dessous):

Mais je n'ai besoin que de l'attribut [dataValues]. Je ne veux pas avoir à utiliser ce bit de JSON pour le récupérer: tagData[0].dataValues.tagId.

Je viens de remarquer: quand il trouve et NE CRÉE PAS, il renverra le JSON pour les résultats de la base de données, mais quand il NE TROUVE PAS et crée, il renvoie le blob JSON inutile (comme ci-dessous) Y a-t-il un moyen de contourner cela?

[ { dataValues:
     { tagId: 1,
       tagName: '#hash',
       updatedAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT),
       createdAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT) },
    _previousDataValues:
     { tagId: 1,
       tagName: '#hash',
       createdAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT),
       updatedAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT) },
    _changed:
     { tagId: false,
       tagName: false,
       createdAt: false,
       updatedAt: false },
    '$modelOptions':
     { timestamps: true,
       instanceMethods: {},
       classMethods: {},
       validate: {},
       freezeTableName: true,
       underscored: false,
       underscoredAll: false,
       paranoid: false,
       whereCollection: [Object],
       schema: null,
       schemaDelimiter: '',
       defaultScope: null,
       scopes: [],
       hooks: {},
       indexes: [],
       name: [Object],
       omitNull: false,
       sequelize: [Object],
       uniqueKeys: [Object],
       hasPrimaryKeys: true },
    '$options':
     { isNewRecord: true,
       '$schema': null,
       '$schemaDelimiter': '',
       attributes: undefined,
       include: undefined,
       raw: true,
       silent: undefined },
    hasPrimaryKeys: true,
    __eagerlyLoadedAssociations: [],
    isNewRecord: false },
  true ]

Au lieu d'obtenir le gros blob comme ci-dessus, j'ai seulement besoin des résultats RAW json (comme ci-dessous):

{ tagId: 1,
       tagName: '#hash',
       updatedAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT),
       createdAt: Fri Dec 25 2015 17:07:13 GMT+1100 (AEDT) },

J'ai utilisé le javascript suivant. J'ai essayé d'ajouter raw: true, Mais cela n'a pas fonctionné?

    // Find or create new tag (hashtag), then insert it into DB with photoId relation
module.exports = function(tag, photoId) {
    tags.findOrCreate( { 
        where: { tagName: tag },
        raw: true
    })
    .then(function(tagData){
        // console.log("----------------> ", tagData[0].dataValues.tagId);
        console.log(tagData);
        tagsRelation.create({ tagId: tagData[0].dataValues.tagId, photoId: photoId })
        .then(function(hashtag){
            // console.log("\nHashtag has been inserted into DB: ", hashtag);
        }).catch(function(err){
            console.log("\nError inserting tags and relation: ", err);
        });
    }).catch(function(err){
        if(err){
            console.log(err);
        }
    });

}

Modifier:

J'ai donc enquêté un peu et il semble que le gros blob JSON ne soit retourné que lorsque Sequelize crée et ne trouve pas.

Y a-t-il un moyen de contourner cela ou non?

Modifier 2:

D'accord, j'ai donc trouvé une solution de contournement, qui pourrait être transformée en fonction réutilisable. Mais s'il y a quelque chose de construit dans Sequelize, je préférerais l'utiliser.

var tagId = "";

// Extract tagId from json blob
if(tagData[0].hasOwnProperty('dataValues')){
    console.log("1");
    tagId = tagData[0].dataValues.tagId;
} else {
    console.log("2");
    console.log(tagData);
    tagId = tagData[0].tagId;
}

console.log(tagId);
tagsRelation.create({ tagId: tagId, photoId: photoId })

Modifier 3:

Donc, je ne pense pas qu'il existe un moyen séquentiel "officiel" pour y parvenir, j'ai donc simplement écrit un module personnalisé qui renvoie les données JSON qui sont nécessaires. Ce module peut être personnalisé et étendu pour s'adapter à diverses situations! Si quelqu'un a des suggestions pour améliorer le module, n'hésitez pas à commenter :)

Dans ce module, nous retournons un objet Javascript. Si vous voulez le transformer en JSON il suffit de le stringifier en utilisant JSON.stringify(data).

// Pass in your sequelize JSON object
module.exports = function(json){ 
    var returnedJson = []; // This will be the object we return
    json = JSON.parse(json);


    // Extract the JSON we need 
    if(json[0].hasOwnProperty('dataValues')){
        console.log("HI: " + json[0].dataValues);
        returnedJson = json[0].dataValues; // This must be an INSERT...so Dig deeper into the JSON object
    } else {
        console.log(json[0]);
        returnedJson = json[0]; // This is a find...so the JSON exists here
    }

    return returnedJson; // Finally return the json object so it can be used
}

Édition 4:

Il existe donc une méthode officielle de séquelle. Reportez-vous à la réponse acceptée ci-dessous.

27
James111

Bien que mal documenté, cela existe dans Sequelize.

Quelques façons:

1. Pour toute réponse objet résultant d'une requête, vous pouvez extraire uniquement les données souhaitées en ajoutant .get({plain:true}) la réponse comme ceci:

Item.findOrCreate({...})
      .spread(function(item, created) {
        console.log(item.get({
          plain: true
        })) // logs only the item data, if it was found or created

Assurez-vous également que vous utilisez la fonction de rappel spread pour votre type de promesse de requête dynamique. Notez également que vous avez accès à une réponse booléenne, created, qui indique si une requête de création a été exécutée ou non.

2. Sequelize fournit l'option raw. Ajoutez simplement l'option {raw:true} et vous ne recevrez que les résultats bruts. Cela fonctionnera sur un tableau de résultats, la première méthode ne devrait pas, car get ne sera pas une fonction d'un tableau.

25
rambossa

Si vous ne voulez travailler qu'avec les valeurs d'une instance essayez d'appeler get({plain: true}) ou toJSON()

tags.findOrCreate( { 
    where: { tagName: tag }
})
.then(function(tagData){
     console.log(tagData.toJSON());
})
6
Rudolf Manusachi

Mis à jour:

Utilisation data.dataValues

db.Message.create({
    userID: req.user.user_id,
    conversationID: conversationID,
    content: req.body.content,
    seen: false
  })
  .then(data => {
    res.json({'status': 'success', 'data': data.dataValues})
  })
  .catch(function (err) {
    res.json({'status': 'error'})
  })
4
KitKit

sequelize-values est un module npm qui vous aide à le faire. Il a des méthodes qui impriment facilement les valeurs sur un seul élément et la liste des résultats (tableau) https://www.npmjs.com/package/sequelize-values

0
Abdul Vajid