Skip to main content
 首页 » 编程设计

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

2024年11月01日4jpfss

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

{“字符串”:{uuid1:“字符串”,uuid1:“字符串”},“字符串”:{uuid:“字符串”}}

或者...

Row_validation_class = UTF8Type 
Default_validation_class = UTF8Type 
Comparator = UUID 

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

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

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

类型错误:无法将 datetime.datetime 与 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 库)会支持这种事情,但我不知道该怎么做。

附注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; 

附:

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

请您参考如下方法:

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

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

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()col_fam.xget() 相同的表单来获取访问者的实际列表。

附言尽量不要为每个请求都创建一个新的 ConnectionPool()。如果必须,请设置较小的池大小。