python驱动程序为大型结果提供了事件/回调方法:
https://datastax.github.io/python-driver/query_paging.html
此外,还有一个batchquery类可用于orm,非常方便:
https://datastax.github.io/python-driver/cqlengine/batches.html?highlight=batchquery
现在,我需要在paged result对象的回调处理程序中执行batchquery,但脚本只是在当前页面上进行迭代。
我想这是因为线程之间无法共享cassandra会话,而batchquery和“paged result”方法使用线程来管理事件设置和回调调用。
你知道怎么神奇地解决这个问题吗?下面是一些代码:
# paged.py
class PagedQuery:
"""
Class to manage paged results.
>>> query = "SELECT * FROM ks.my_table WHERE collectionid=123 AND ttype='collected'" # define query
>>> def handler(page): # define result page handler function
... for t in page:
... print(t)
>>> pq = PagedQuery(query, handler) # instantiate a PagedQuery object
>>> pq.finished_event.wait() # wait for the PagedQuery to handle all results
>>> if pq.error:
... raise pq.error
"""
def __init__(self, query, handler=None):
session = new_cassandra_session()
session.row_factory = named_tuple_factory
statement = SimpleStatement(query, fetch_size=500)
future = session.execute_async(statement)
self.count = 0
self.error = None
self.finished_event = Event()
self.query = query
self.session = session
self.handler = handler
self.future = future
self.future.add_callbacks(
callback=self.handle_page,
errback=self.handle_error
)
def handle_page(self, page):
if not self.handler:
raise RuntimeError('A page handler function was not defined for the query')
self.handler(page)
if self.future.has_more_pages:
self.future.start_fetching_next_page()
else:
self.finished_event.set()
def handle_error(self, exc):
self.error = exc
self.finished_event.set()
# main.py
# script using class above
def main():
query = 'SELECT * FROM ks.my_table WHERE collectionid=10 AND ttype=\'collected\''
def handle_page(page):
b = BatchQuery(batch_type=BatchType.Unlogged)
for obj in page:
process(obj) # some updates on obj...
obj.batch(b).save()
b.execute()
pq = PagedQuery(query, handle_page)
pq.finished_event.wait()
if not pq.count:
print('Empty queryset. Please, check parameters')
if __name__ == '__main__':
main()
1条答案
按热度按时间ohfgkhjo1#
由于您不能在responsefuture的事件循环中执行查询,因此您可以只迭代并将对象发送到队列。我们确实有kafka队列来持久化对象,但在本例中,线程安全的python队列工作得很好。