2013-02-10 170 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())