使用Python和datetime模块,基于TimeUUIDType获取Cassandra的列范围

时间:2013-08-02 16:10:06

标签: python nosql cassandra pycassa

我有一个像这样的表格设置:

{"String" : {uuid1 : "String", uuid1: "String"}, "String" : {uuid : "String"}}

或者...

Row_validation_class = UTF8Type
Default_validation_class = UTF8Type
Comparator = UUID

(它基本上将网站作为行标签,并且基于datetime.datetime.now()在Cassandra中使用TimeUUIDType动态生成列,并将字符串作为值)

我希望使用Pycassa根据行和列检索数据切片。但是,在其他(较小的)表上我已经完成了这个,但是通过下载整个数据集(或至少过滤到一行),然后有一个有序的字典,我可以与datetime对象进行比较。

我希望能够使用Pycassa multiget或get_indexed_slice函数来拉取某些列和行。是否存在允许在datetime上过滤的类似内容。我当前的所有尝试都会导致以下错误消息:

TypeError: can't compare datetime.datetime to UUID

到目前为止,我设法提出的最好的是...

def get_number_of_visitors(site, start_date, end_date=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S:%f")):
    pool = ConnectionPool('Logs', timeout = 2)
    col_fam = ColumnFamily(pool, 'sessions')
    result = col_fam.get(site)
    number_of_views = [(k,v) for k,v in col_fam.get(site).items() if get_posixtime(k) > datetime.datetime.strptime(str(start_date), "%Y-%m-%d %H:%M:%S:%f") and get_posixtime(k) < datetime.datetime.strptime(str(end_date), "%Y-%m-%d %H:%M:%S:%f")]
    total_unique_sessions = len(number_of_views)
    return total_unique_sessions

将get_posixtime定义为:

def get_posixtime(uuid1):
    assert uuid1.version == 1, ValueError('only applies to type 1')
    t = uuid1.time
    t = (t - 0x01b21dd213814000L)
    t = t / 1e7
    return datetime.datetime.fromtimestamp(t)

这似乎不起作用(没有返回我期望的数据),也觉得它不应该是必要的。我正在使用以下方法创建列时间戳:

timestamp = datetime.datetime.now()

有人有什么想法吗?感觉这就是Pycassa(或其他python库)会支持的东西,但我无法弄清楚如何去做。

P.S。 cqlsh:

描述的表模式
CREATE COLUMNFAMILY sessions (
  KEY text PRIMARY KEY
) WITH
  comment='' AND
  comparator='TimeUUIDType' AND
  row_cache_provider='ConcurrentLinkedHashCacheProvider' AND
  key_cache_size=200000.000000 AND
  row_cache_size=0.000000 AND
  read_repair_chance=1.000000 AND
  gc_grace_seconds=864000 AND
  default_validation=text AND
  min_compaction_threshold=4 AND
  max_compaction_threshold=32 AND
  row_cache_save_period_in_seconds=0 AND
  key_cache_save_period_in_seconds=14400 AND
  replicate_on_write=True;

P.S。

我知道您可以在Pycassa中指定列范围,但我无法保证范围的起始值和结束值将包含每个行的条目,因此列可能不存在。

1 个答案:

答案 0 :(得分:2)

您确实希望使用column_startcolumn_finish参数向get()multiget()get_count(),{{1}请求“切片”列对于TimeUUIDType比较器,pycassa实际上接受get_range()个实例或这两个参数的时间戳;它将在内部将它们转换为具有匹配时间戳组件的类似TimeUUID的形式。专门针对working with TimeUUIDs的文档部分提供了更多详细信息。

例如,我会像这样实现你的功能:

datetime

您可以使用与def get_number_of_visitors(site, start_date, end_date=None): """ start_date and end_date should be datetime.datetime instances or timestamps like those returned from time.time(). """ if end_date is None: end_date = datetime.datetime.now() pool = ConnectionPool('Logs', timeout = 2) col_fam = ColumnFamily(pool, 'sessions') return col_fam.get_count(site, column_start=start_date, column_finish=end_date) col_fam.get()相同的表单来获取实际的访问者列表。

P.S。尽量不为每个请求创建新的col_fam.xget()。如果必须,请设置较小的池大小。