web-dev-qa-db-ja.com

日時をCassandra 1.2タイムスタンプ列に挿入する方法

[〜#〜] important [〜#〜]今日この問題に対処している場合は、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タイムスタンプ列に格納できるようにする正しい方法は何ですか?

前もって感謝します!

10

Abhiは、これはエポックからのミリ秒をcqlshからの長い値として使用して実行できるとすでに述べています。次に、Pythonコードで機能させる必要があります。

Cqlライブラリを使用する場合、この変換(日時からエポックからのミリ秒へ)は行われないため、更新を機能させ、精度を維持するには、日時をエポックからミリ秒に変換する必要があります。

ソースこの有用な質問の使用: 日時からエポックからミリ秒を取得 、特にこの関数(私が行った小さな変更に注意してください) :

解決策

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)

日時をエポックからのミリ秒数を含む長い値に変換できます。それだけで、更新はタイムスタンプに長い値を使用して同等の形式に変換されます。

それが他の誰かに役立つことを願っています

7

Cqlshでそれを行う方法を教えてくれます。これを試して

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

日時の同等の長い値2013-05-13 15:12:511368438171000

10
abhi

私にとってはそれは直接動作します

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

何かを変換する必要はありません。したがって、Pythonでは、datetime値を文字列として使用して実行できます。

cursor.execute("UPDATE test SET ts=:ts WHERE id=:id;",
    dict(ts=your_datetime.isoformat(), id=id))
5
webjunkie

2年前の質問であることは知っていますが、誰かが答えを探しに来た場合は、タイムスタンプを使用する代わりに日時インスタンスを使用してください。 Pythonドライバーは、整数/浮動小数点数をスマートに処理する必要があります。

1
zonked.zonda

ほとんどの解決策は有効ですが、もっと簡単なものを提案したいと思います。

from datetime import datetime

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

update test set last_sent = my_date where id = 'someid'
1
Patrick