Sails.js modèle d'insérer ou de mettre à jour des enregistrements
Essayé Sails.js et je suis en train d'écrire une application que l'importation des données à partir d'un tiers de l'API et l'enregistre dans une table MySQL. Fondamentalement, je suis en train de synchroniser les données sur mon app pour de plus amples analyse, la mise à jour de mon dossier ou la création de nouveaux records en tant que de besoin.
J'ai regardé à travers les Voiles de l'API, et je vois des méthodes pour trouver, créer et mettre à jour des enregistrements, mais pas de méthode intégrée pour insérer/mettre à jour des enregistrements en fonction de la situation. Ai-je oublier quelque chose, ou ai-je besoin pour mettre en œuvre cette moi-même?
Si je mettre en place moi-même, personne ne sait d'un bon modèle de conception pour insérer/mettre à jour?
C'est ce que je pense qu'il pourrait ressembler à...
_.each(importedRecords, function(record){
MyModel.find({id: record.id}).exec(function findCB(err, found){
if(found.length){
MyModel.update(record.id, task).exec(function(err, updated){
if(err) { //returns if an error has occured, ie id doesn't exist.
console.log(err);
} else {
console.log('Updated MyModel record '+updated[0].name);
}
});
}else{
MyModel.create(record).exec(function(err, created){
if(err) { //returns if an error has occured, ie invoice_id doesn't exist.
console.log(err);
} else {
console.log('Created client record '+created.name);
}
});
}
});
});
Suis-je dans la bonne direction, ou est-il une solution plus élégante?
Aussi, je fais face à beaucoup de différents modèles de cette application, qui serait un moyen de recréer ce bloc de code, et dans chacun de mes modèles. Est il possible que je peux étendre le Modèle de base de l'objet à ajouter cette fonctionnalité pour tous les modèles.
Grâce,
Jean
OriginalL'auteur Critical Mash | 2014-09-19
Vous devez vous connecter pour publier un commentaire.
J'ai réécrit Critique Purée de code, donc son chemin à moins de code, et plus générique.
Maintenant, vous pouvez appeler updateOrCreate de la même manière que vous appelez findOrCreate. Et ça ressemble à ça:
De sorte que vous pouvez écrire des critères de la même façon. pas besoin de travailler sur la touche, et le code est beaucoup plus simple.
oui bien sûr. s'il vous plaît ne faire une pull request.
exactement liée à la question et de "quelque chose qui manque dans les voiles". merci! @AaronWagner toute demande d'extraction de mise à jour?
J'ai ajouté à mon config/models.js fichier sous
module.exports.models = {
Il n'a pas de travail là. Got méthode non défini erreur lorsque je l'ai appelé de mon contrôleur. J'ai donc ajouté comme une méthode sur le modèle que j'ai essayé de l'utiliser sur et il y a travaillé. Donc +1, super réponse. Je ne sais pas pourquoi il ne fonctionne pas dans les modèles de fichier, comme vous l'avez suggéré.Hey. @Loubot j'ai mis à jour le code pour prendre en charge les promesses et sa fonctionne maintenant.
OriginalL'auteur Stas Arshanski
Voiles 0.10 a
findOrCreate(criteria, attributes, callback)
, voir Voiles Docs.criteria
est les critères de recherche pour "trouver" un peu (même syntaxe que find()).attributes
de données est utilisée si elle n'est pas trouvée pour "créer" bits (même syntaxe que de créer()).Voici un exemple:
MyModel.findOrCreate({name:'Walter'},{name:'Jessie'}, function (err, record){
console.log('What\'s cookin\' '+record.name+'?');
Notez également qu'il existe d'autres composite requête méthodes décrites dans le Ligne de flottaison référentiel (voir la tests pour des exemples) et Ligne de flottaison de la documentation:
Comme pour donnant sur quelque chose, eh bien il est là, mais il n'est pas le principal des Voiles de la documentation et pourtant si la réponse est oui et non, donc, pas de panique 🙂
Vous êtes les bienvenus. Cela ressemble à des fonctionnalités utiles. Peut-être que vous devriez présenter une Amélioration de billets pour la ligne de Flottaison.
Voiles Docs lien pour findOrCreate() est cassé, manque le bang. sailsjs.org/#!/documentation/de référence/de la ligne de flottaison/modèles/...
À droite, il semble qu'il serait utile d'avoir à la fois
upsert
etfindOrCreate
méthodes qui fournissent un drapeau de présence et unnext()
méthode pour aller de l'avant pourinsert
oucreate
, respectivement.concernant les Voiles docs que vous l'avez mentionné, il semble que vous pouvez passer un tableau d'objets pour les deux critères et record. Est-ce à vérifier par le biais de chacun des critères de l'objet et, s'il n'existe pas, la carte à l'index de l'enregistrement de l'objet?
OriginalL'auteur Kenneth Benjamin
Votre solution est la bonne. Il n'y a pas d'autre moyen de le faire avec la ligne de flottaison (l'ORM de sails.js).
Mais plusieurs bases de données ont des fonctions pour ce cas:
MySQL
REPLACE INTO table SET id = 42, foo = 'bar';
(avec une clé primaire ou unique. Assez de merde si vous utilisez auto_increment 😉
De la ligne de Flottaison, vous pouvez utiliser le Modèle.query()-Fonction pour exécuter SQL directe (voir: http://sailsjs.org/#/documentation/reference/waterline/models/query.html)
MongoDB
La upsert drapeau signifie: Si vous ne pouvez pas mettre à jour parce que vous ne trouverez pas n'importe quoi avec la requête de créer cet élément!
De la ligne de Flottaison, vous pouvez utiliser le Modèle.natif()-Fonction pour exécuter directement mongoDB-Commandes (voir: http://sailsjs.org/#/documentation/reference/waterline/models/native.html)
Conclusion
Vous vous avez besoin d'une rapidité d'exécution (et de la corse si vous avez beaucoup de beaucoup de demande) je suggère d'utiliser le natif/sql-fonctions. Mais en général, je suis vraiment fan de la flexibilité d'un ORM-Système et chaque fois que vous utilisez la base de données des fonctions spécifiques, il est plus difficile à manipuler.
OriginalL'auteur mdunisch
Grâce user3351722, je préfère utiliser l'ORM système. J'ai juste essayé de mise en œuvre de la solution ci-dessus comme un Modèle général de la méthode. (Basé sur Héritent des attributs et des fonctions de cycle de vie Sails.js modèles).
J'ai édité config/models.js et ajout d'une nouvelle fonction
insertOrUpdate
qui prend le nom de la colonne d'index, les données que je veux insérer ou de mettre à jour et d'une fonction de rappel.Ce ne travaillons qu'avec des tables et des collections qui ont un index. Je ne sais pas comment faire pour connaître le nom de la clé à partir d'un modèle de la ligne de flottaison si je passe dans le champ nom d'une chaîne de caractères.
Voici comment vous pouvez utiliser la méthode à l'intérieur d'un contrôleur...
J'ai essayé cette méthode avec trois modèles différents et, donc bon. Ils sont tous des tables MySQL et les modèles ont tous un index définies. Votre kilométrage peut très si vous utilisez un autre magasin de données.
Si quelqu'un voit un moyen d'améliorer sur ce point, s'il vous plaît laissez-nous savoir.
OriginalL'auteur Critical Mash
C'est comment je le fais: - je prolonger la config/models.js pour inclure la fonctionnalité et il vérifie pour voir si la carte a les bonnes méthodes. Vous pouvez l'appeler comme une promesse ou normalement.
Race
état, depuis l'enregistrement peut être créé après la recherche. Cela est vrai pour tous, mais les Bases de données qui prennent en charge les transactions. Techniquement parlant, il est préférable de simplement appeler lecreate
la fonction et de l'écouter pour une erreur qui serait à son tour vous dire de mettre à jour à la place.OriginalL'auteur scott