2017-03-07 81 views
2

我用pg-promise与发生器交易得到了一些奇怪的东西。
这就是我想要的:Pg-promise:交易问题

  1. 获取或注册用户(getOrRegisterUser)
  2. 待办事项批次的东西(4个插入发生器)
  3. 最后,结果做最后插入(发电机registerCall) getOrRegisterCurrentParkingIfProvided发电机

这里是我的代码:

db.tx(function (t) { 
      return t.task.call(params, getOrRegisterUser).then(function (user) { 
       params.masterId = user.id; // NOTICE : MY USER ID DATABASE 
       return t.batch([ 
        t.task.call(params, registerNewPhones), 
        t.task.call(params, registerNewPlate), 
        t.task.call(params, registerNewSubscriptions), 
        t.task.call(params, getOrRegisterCurrentParkingIfProvided) 
       ]).then(function (result) { 
        params.ParkingId = (result[3] !== undefined) ? result[3].id : null; 
        return t.task.call(params, registerCall); 
       }) 
      }); 
}).then(function() { 
    // job done 
    resolve(); 
}).catch(function (err) { 
    console.log(err); 
    reject(err); 
}); 

我在第二发生器(registerNewPhones)此错误消息:

severity: 'ERREUR', 
code: '23503', 
detail: 'La clé (customer)=(3) n\'est pas présente dans la table « users ».', 

什么办法解决呢?我尝试了这样的交易:https://github.com/vitaly-t/pg-promise#nested-transactionshttps://github.com/vitaly-t/pg-promise#synchronous-transactions,但有一些未知的情况,我仍然在某处出错。

感谢

PS:我知道,这些发电机的实施是无罪所以...

编辑:如果你真的想看到代码

let squel = require('squel'); 
// squel with PostgresSQL syntax 
let squelPostgres = squel.useFlavour('postgres'); 

registerNewPhones:

// Register all new phones numbers for user 
function * registerNewPhones(t) { 

    let params = t.ctx.context; 

    let findPhonesForUserQuery = squelPostgres 
     .select() 
     .from("HELPDESK.phones") 
     .field("number") 
     .where("customer = ?", params.masterId) 
     .toString(); 

    let registerPhoneForUser = squelPostgres 
     .insert() 
     .into("HELPDESK.phones") 
     .set("customer", params.masterId); 

    // find the already known phone number(s) for this user 
    return t.any(findPhonesForUserQuery).then(function (result) { 

     // data 
     let phones = (params.hasOwnProperty("phones") ? params.phones : []); 

     let alreadyRegisteredPhones = result.map(function (element) { 
      return element.number; 
     }); 

     // filter data 

     let phonesToRegister = phones.filter(function (aPhoneNumber) { 
      return alreadyRegisteredPhones.indexOf(aPhoneNumber) == -1; 
     }); 

     // create queries 
     let queries = phonesToRegister.map(function (phone) { 
      return db.none(
       registerPhoneForUser 
        .clone() 
        .set("number", phone) 
        .toString() 
      ); 
     }); 
     return t.batch(queries); 
    }); 

} 

和生成器getOrRegisterUser:

function * getOrRegisterUser(t) { 

    let params = t.ctx.context; 

    // QUERIES: 
    let findUserQuery = squelPostgres 
     .select() 
     .from("HELPDESK.users") 
     .field("id") 
     .where("registered_id = ?", params.userId) 
     .toString(); 

    let insertUserQuery = squelPostgres 
     .insert() 
     .into("HELPDESK.users") 
     .setFields({ 
      name: params.userName, 
      registered_id: params.userId, 
      typeOfAccount: 'BASIC', 
      email: params.email 
     }) 
     .returning('id') 
     .toString(); 

    let user = yield t.oneOrNone(findUserQuery); 
    return yield user || t.one(insertUserQuery); 
} 
+0

我们怎样才能知道什么'registerNewPhones'造成的错误,如果你甚至不显示它的实施? :)为什么你过度使用这样的数据库任务也不清楚。从技术上讲,交易不需要任何内部任务,它们在交易中没有多大价值。 –

+0

你至少需要发布'getOrRegisterUser'和'registerNewPhones'的代码,所以你可以看到你是如何得到错误的。但是,鉴于错误是数据库级别的,数据库逻辑可能是原因。 –

+0

我刚加入。正如你所看到的,我使用压制 – jy95

回答

1

的问题是ES6发电机功能registerNewPhones内:

return t.any(findPhonesForUserQuery)... 

它不yield承诺的结果,这是需要ES6发电机的功能。

即它必须是:

return yield t.any(findPhonesForUserQuery)...