2013-02-10 111 views
2

我想存儲的意見在卡桑德拉一個博客,都拿出了這個模式(接到here想法):寬行 - 越來越怪異的錯誤

create table comments (slug varchar, ts timestamp, value text, primary key (slug,ts)); 

使用CQL(我使用的node.js與Helenus司機)我想添加一些數據吧,這裏就是我這麼遠:

var helenus = require('helenus'), 
    pool = new helenus.ConnectionPool({ 
     hosts: ['localhost:9160'], 
     keyspace: 'blogks' 
    }); 

pool.on('error', function(err) { 
    console.error(err.name, err.message); 
}); 



module.exports.addComment = function(slug, comment,callback){ 
    pool.connect(function(connErr,keyspace){ 
     if(connErr){ 
      callback(connErr); 
      return; 
     } 

     var cql = "INSERT INTO comments (slug,ts,value) VALUES (?, ?, ?);"; 
     pool.cql(cql,[slug,serializeDate(new Date()),serializeJSON(comment)],function(err,results){ 
      callback(err,results); 
     }); 
    }); 
} 

function serializeDate(date){ 
    var dateSerializer = new helenus.Marshal('DateType'); 
    return dateSerializer.serialize(date).toString('hex'); 
} 

function serializeJSON(data){ 
    var utf8Serializer = new helenus.Marshal('UTF8Type'); 
    return utf8Serializer.serialize(JSON.stringify(data)).toString("hex"); 
} 

的想法是,你可以在評論JSON對象傳遞給這種方法,並推到卡桑德拉。我打電話像這樣進行測試:

var comments = require('./comments.js'); 

comments.addComment("myslug",{id:2,name:"Alex",comment:"Hello!"},function(e,r){ 
    console.log(e); 
    console.log(r); 
}) 

但每當我做(我嘗試過各種CQL驅動程序),我得到這個神祕的錯誤消息:

[HelenusInvalidRequestException: unable to coerce 'value' to a formatted date (long)] name: 'HelenusInvalidRequestException' 

我試圖改變的時間戳是所有不同的數據類型,但沒有運氣。非常奇怪的是,起初,我的主鍵本身就是slu and,然後它確實奏效。但是,我想按時間順序將所有註釋存儲在一行中,因此我不得不採用這種使用兩列作爲主鍵的方法。有任何想法嗎?

編輯因此,基於rs_atl's建議,這裏就是我試過:

這條線:

dateSerializer.serialize(date).toString('hex') 

其實回報垃圾(0000013ccfacf5c4)這樣做,我一定誤解了如何使用API。所以這裏是我試圖改爲:

我試過只是new Date().getTime()哪些在JS確實返回Unix風格的時代,但沒有工作我得到了同樣的錯誤。

moment().format("YYYY-MM-DD HH:mm:ss") 

這似乎是回到了正確的格式,但再次:然後我用moment.js嘗試格式化字符串嘗試。同樣的錯誤。然後我試過這個:

moment().format("YYYY-MM-DD HH:mm") + "Z" 

沒有運氣。然後我嘗試了這個:

moment().format("YYYY-MM-DD HH:mmZ") 

它確實在最後添加了時區信息,但仍然沒有運氣。有任何想法嗎?

+0

你肯定知道你沒有一個字節序的問題? – 2013-02-12 19:26:40

+0

@rs_atl嗯......我不太瞭解endianness來回答這個問題。我能做的最好的事情就是指向Helenus中的代碼行,它可以對日期進行編碼(從我可以告訴它只是獲得unix風格的時代和編碼這一點)。 https://github.com/simplereach/helenus/blob/master/lib/marshal/serializers.js#L149 – BFree 2013-02-12 20:15:40

回答

1

看來你正在使用錯誤的CQL版本。您希望使用CQL 3.0.0,但驅動程序默認爲CQL2。您需要在初始化中指定正確的CQL版本。

pool = new helenus.ConnectionPool({ 
    hosts: ['localhost:9160'], 
    keyspace: 'blogks', 
    cqlVersion: '3.0.0' 
}); 

也請確保您使用的是Helenus的最新版本(0.6.2截止)。

+0

謝謝!真的很感激它。 – BFree 2013-02-12 21:29:16

1

我不能完全肯定這條線的輸出是什麼:

return dateSerializer.serialize(date).toString('hex');

但是這是你的問題。看起來你並沒有輸出Cassandra能夠理解的有效日期。有效的日期是:

  1. 一個Unix風格的epoch作爲long值。

  2. 以下列形式之一的字符串:

    YYYY-MM-DD HH:MM
    YYYY-MM-DD HH:MM:SS
    YYYY-MM-DD HH:MMZ
    YYYY-MM-DD HH:MM:SSZ
    YYYY-MM-dd'T'HH:毫米
    YYYY-MM-dd'T'HH:MMZ
    YYYY-MM-dd'T'HH:MM: ss
    yyyy-mm-dd'T'HH:mm:ssZ
    yyyy-mm-dd
    YYYY-MM-DDZ

檢查以確保你正在寫這些有效的時間戳類型之一。

+0

感謝您的意見和幫助。看到我的更新,我嘗試了你的建議,但仍然沒有運氣:( – BFree 2013-02-12 18:37:25

0

對於時間戳,我總是用毫秒來表示時間的int。

嘗試:

Date.now() 

代替:

serializeDate(new Date())