10

重要 如果您今天正在处理这个问题,请使用来自 datastax 的新 cassandra-driver(即 import cassandra),因为它解决了大多数常见问题并且不再使用旧的 cql 驱动程序,它已经过时了!这个问题在新驱动程序甚至还在开发之前就已经很老了,我们不得不使用一个名为 cql 的不完整的旧库(import cql <--不再使用它,移至新驱动程序)。

简介 我正在使用 python 库 cql 访问 Cassandra 1.2 数据库。在数据库中,我有一个带有时间戳列的表,在我的 Python 代码中,我有一个要插入到列中的日期时间。示例如下:

桌子

CREATE TABLE test (
     id text PRIMARY KEY,
     last_sent timestamp
);

编码

import cql
import datetime
...
cql_statement = "update test set last_sent = :last_sent where id =:id"
rename_dict = {}
rename_dict['id'] = 'someid'
rename_dict['last_sent'] = datetime.datetime.now()
cursor.execute (cql_statement, rename_dict)

问题

当我执行代码时,实际执行的 cql 语句是这样的:

update test set last_sent =2013-05-13 15:12:51 where id = 'someid'

然后它失败并出现错误

 Bad Request: line 1:XX missing EOF at '-05'

问题似乎是 cql 库在运行查询之前没有转义('')或转换日期时间。

问题 在不手动转义日期并能够将更精确的完整时间戳存储到 cassandra 时间戳列中的情况下,正确的方法是什么?

提前致谢!

4

5 回答 5

10

我可以告诉你如何在 cqlsh 中做到这一点。尝试这个

update test set last_sent =1368438171000 where id = 'someid'

日期时间的等效长值2013-05-13 15:12:511368438171000

于 2013-05-14T05:34:37.630 回答
7

abhi 是否已经说过这可以使用自纪元以来的毫秒作为 cqlsh 的长值来完成,现在我们需要让它在 Python 代码中工作。

当使用 cql 库时,这种转换(从日期时间到自纪元以来的毫秒数)不会发生,因此为了使更新工作并且仍然具有将日期时间转换为自纪元以来的毫秒数所需的精度。

来源 使用这个有用的问题:Getting millis since epoch from datetime,特别是这个函数(注意我所做的小改动):

解决方案

import datetime

def unix_time(dt):
    epoch = datetime.datetime.utcfromtimestamp(0)
    delta = dt - epoch
    return delta.total_seconds()

def unix_time_millis(dt):
    return long(unix_time(dt) * 1000.0)

对于此示例,代码为:

cql_statement = "update test set last_sent = :last_sent where id =:id"
rename_dict = {}
rename_dict['id'] = 'someid'
rename_dict['last_sent'] = unix_time_millis(datetime.datetime.now())
cursor.execute (cql_statement, rename_dict)

您可以将日期时间转换为包含自纪元以来的毫秒数的长值,仅此而已,使用时间戳的长值将更新转换为等效形式。

希望它可以帮助别人

于 2013-05-14T16:06:58.487 回答
5

对我来说,它直接与

update test set last_sent = '2013-05-13 15:12:51' where id = 'someid'

无需转换任何东西。因此,在 Python 中,您可以使用日期时间值作为字符串来执行此操作:

cursor.execute("UPDATE test SET ts=:ts WHERE id=:id;",
    dict(ts=your_datetime.isoformat(), id=id))
于 2013-09-19T15:15:44.900 回答
1

大多数解决方案都是有效的,我只想建议一个更简单的解决方案:

from datetime import datetime

my_date = int(float(datetime.now().strftime("%s.%f"))) * 1000

update test set last_sent = my_date where id = 'someid'
于 2015-10-21T08:03:26.303 回答
1

我知道这是一个 2 年前的问题,但是如果有人来寻找答案,请使用 datetime 实例而不是使用时间戳。不过,Python 驱动程序应该巧妙地处理整数/浮点数。

于 2016-04-25T00:39:20.960 回答