2013-08-18 7 views
13

बनाएँ या अपडेट करें मैं अपने नोडजेस प्रोजेक्ट में सेक्विलाइज़ का उपयोग कर रहा हूं और मुझे एक समस्या मिली है कि मुझे हल करने में कठिनाई हो रही है। असल में मेरे पास एक क्रॉन है जो किसी ऑब्जेक्ट (इस मामले के लिए, कार्टून) के रूप में मेरे डेटाबेस पर इसे डालने से सर्वर से ऑब्जेक्ट्स की सरणी प्राप्त करता है। लेकिन अगर मेरे पास पहले से ही एक वस्तु है, तो मुझे इसे अपडेट करना होगा।Sequelize

असल में मेरे पास ऑब्जेक्ट्स की एक सरणी है और आप बल्कक्रेट() विधि का उपयोग कर सकते हैं। लेकिन जैसा कि क्रॉन फिर से शुरू होता है, यह इसे हल नहीं करता है, इसलिए मुझे एक अपरिवर्तनीय झंडा के साथ कुछ प्रकार के अपडेट की आवश्यकता थी। और मुख्य मुद्दा: मेरे पास एक कॉलबैक होना चाहिए जो इन सभी रचनाओं या अद्यतनों के ठीक बाद एक बार आग लगती है। क्या किसी के पास कोई विचार है कि मैं यह कैसे कर सकता हूं? ऑब्जेक्ट की सरणी पर इटरेट करें .. इसे बनाना या अपडेट करना और फिर एक कॉलबैक प्राप्त करना?

ध्यान

उत्तर

18

से docs, ऑब्जेक्ट होने के बाद आपको अपडेट करने के लिए where से पूछताछ करने की आवश्यकता नहीं है।इसके अलावा, वादा के उपयोग को आसान बनाने चाहिए कॉलबैक:

कार्यान्वयन

function upsert(values, condition) { 
    return Model 
     .findOne({ where: condition }) 
     .then(function(obj) { 
      if(obj) { // update 
       return obj.update(values); 
      } 
      else { // insert 
       return Model.create(values); 
      } 
     } 
    }) 
} 

प्रयोग

upsert({ first_name: 'Taku' }, { id: 1234 }).then(function(result){ 
    res.status(200).send({success: true}); 
}); 

नोट

  1. इस operati

    1. मूल्य पर नज़र: पर परमाणु नहीं है
    2. 2 नेटवर्क कॉल

    जो इसे फिर से लगता है कि दृष्टिकोण और शायद सिर्फ एक नेटवर्क कॉल में मानों को अपडेट और या तो उचित है इसका मतलब है बनाता है लौटा (यानी rows_affected) और अपडेट करें कि

  2. अपडेट ऑपरेशन सफल होने पर सफलता प्राप्त करें। ऐसा इसलिए है क्योंकि संसाधन मौजूद है या नहीं, इस सेवा की ज़िम्मेदारी में नहीं है।
2

ध्वनि पसंद करती है आप एक async.each के अंदर अपने Sequelize कॉल रैप करने के लिए चाहते हैं के लिए धन्यवाद।

+0

मैं सेक्विलाइज से अपडेट पर कुछ परेशान विकल्प की उम्मीद कर रहा था लेकिन यह सड़क मानचित्र से बाहर लगता है। मैं कोशिश करूँगा धन्यवाद! –

1

यह कस्टम इवेंट एमिटर के साथ किया जा सकता है।

मान लें कि आपका डेटा डेटा नामक चर में है।

new Sequelize.Utils.CustomEventEmitter(function(emitter) { 
    if(data.id){ 
     Model.update(data, {id: data.id }) 
     .success(function(){ 
      emitter.emit('success', data.id); 
     }).error(function(error){ 
      emitter.emit('error', error); 
     }); 
    } else { 
     Model.build(data).save().success(function(d){ 
      emitter.emit('success', d.id); 
     }).error(function(error){ 
      emitter.emit('error', error); 
     }); 
    } 
}).success(function(data_id){ 
    // Your callback stuff here 
}).error(function(error){ 
    // error stuff here 
}).run(); // kick off the queries 
0

आप sequelize में findOrCreate और फिर update तरीकों का उपयोग कर सकते हैं। यहाँ async.js

async.auto({ 
    getInstance : function(cb) { 
     Model.findOrCreate({ 
     attribute : value, 
     ... 
     }).complete(function(err, result) { 
     if (err) { 
      cb(null, false); 
     } else { 
      cb(null, result); 
     } 
     }); 
    }, 
    updateInstance : ['getInstance', function(cb, result) { 
     if (!result || !result.getInstance) { 
     cb(null, false); 
     } else { 
     result.getInstance.updateAttributes({ 
      attribute : value, 
      ... 
     }, ['attribute', ...]).complete(function(err, result) { 
      if (err) { 
      cb(null, false); 
      } else { 
      cb(null, result); 
      } 
     }); 
     } 
     }] 
    }, function(err, allResults) { 
     if (err || !allResults || !allResults.updateInstance) { 
     // job not done 
     } else { 
     // job done 
    }); 
}); 
6

यह एक पुरानी सवाल हो सकता है के साथ एक नमूना है, लेकिन इस मैं क्या किया है:

var updateOrCreate = function (model, where, newItem, onCreate, onUpdate, onError) { 
    // First try to find the record 
    model.findOne({where: where}).then(function (foundItem) { 
     if (!foundItem) { 
      // Item not found, create a new one 
      model.create(newItem) 
       .then(onCreate) 
       .catch(onError); 
     } else { 
      // Found an item, update it 
      model.update(newItem, {where: where}) 
       .then(onUpdate) 
       .catch(onError); 
      ; 
     } 
    }).catch(onError); 
} 
updateOrCreate(
    models.NewsItem, {title: 'sometitle1'}, {title: 'sometitle'}, 
    function() { 
     console.log('created'); 
    }, 
    function() { 
     console.log('updated'); 
    }, 
    console.log); 
+2

संकेत: त्रुटि प्रबंधन के लिए वादा श्रृंखला का उपयोग करें और अपने कोड का 50% बचाएं :) –

+0

^^ वास्तव में मैं टिप्पणी करने वाला था। लेकिन आप तेज़ थे। – omerjerk

6

आप upsert उपयोग कर सकते हैं यह तरीका आसान है।

क्रियान्वयन विवरण: सम्मिलित करें अपवाद है जब unique_constraint अद्यतन:

MySQL - अपवाद हैंडलिंग के साथ एक अस्थायी समारोह के रूप में कार्यान्वित - पर नकली चाबी
अद्यतन किसी एक क्वेरी सम्मिलित मूल्यों के रूप में कार्यान्वित PostgreSQL को महत्व देता है
SQLite - INSERT के दो प्रश्नों के रूप में कार्यान्वित; अद्यतन करें। इसका मतलब है कि अद्यतन की पंक्ति पहले से ही अस्तित्व में है कि क्या या नहीं

+0

अपरर्ट का उपयोग करें, लेकिन अगर यह एक सम्मिलित करता है, तो आपको फिर सम्मिलित ऑब्जेक्ट प्राप्त करने की आवश्यकता होगी :(- http://stackoverflow.com/a/29071422/48348 –

0

यहाँ परवाह किए बिना निष्पादित किया जाता है कि या तो अपडेट DeviceID एक सरल उदाहरण है -> pushToken मैपिंग या यह बनाता है:

var Promise = require('promise'); 
var PushToken = require("../models").PushToken; 

var createOrUpdatePushToken = function (deviceID, pushToken) { 
    return new Promise(function (fulfill, reject) { 
    PushToken 
     .findOrCreate({ 
     where: { 
      deviceID: deviceID 
     }, defaults: { 
      pushToken: pushToken 
     } 
     }) 
     .spread(function (foundOrCreatedPushToken, created) { 
     if (created) { 
      fulfill(foundOrCreatedPushToken); 
     } else { 
      foundOrCreatedPushToken 
      .update({ 
       pushToken: pushToken 
      }) 
      .then(function (updatedPushToken) { 
       fulfill(updatedPushToken); 
      }) 
      .catch(function (err) { 
       reject(err); 
      }); 
     } 
     }); 
    }); 
}; 
6

मैं Ataik का विचार पसंद आया, लेकिन यह थोड़ा छोटा कर दिया:

function updateOrCreate (model, where, newItem) { 
    // First try to find the record 
    return model 
    .findOne({where: where}) 
    .then(function (foundItem) { 
     if (!foundItem) { 
      // Item not found, create a new one 
      return model 
       .create(newItem) 
       .then(function (item) { return {item: item, created: true}; }) 
     } 
     // Found an item, update it 
     return model 
      .update(newItem, {where: where}) 
      .then(function (item) { return {item: item, created: false} }) ; 
    } 
} 

उपयोग:

updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'}) 
    .then(function(result) { 
     result.item; // the model 
     result.created; // bool, if a new item was created. 
    }); 

वैकल्पिक: यहां से निपटने त्रुटि जोड़ने के लिए, लेकिन मैं दृढ़ता से सभी श्रृंखला के लिए सिफारिश एक अनुरोध के वादे और अंत में एक त्रुटि हैंडलर है।

updateOrCreate(models.NewsItem, {slug: 'sometitle1'}, {title: 'Hello World'}) 
    .then(..) 
    .catch(function(err){}); 
संबंधित मुद्दे