2016-08-23 6 views
0

モデルは次のとおりです。Rand APIを使用したCassandraモデルのページング

# File: models.py 
from uuid import uuid4 

from cassandra.cqlengine.models import Model 
from cassandra.cqlengine import columns 


class StudentModel(Model): 
    __table_name__ = 'students' 
    id = columns.UUID(primary_key=True, default=uuid4) 
    name = columns.Text(index=True, required=True) 

    def __json__(self): 
     return {'id': str(self.id), 
       'name': self.name} 

このモデルのデータを扱うボトルアプリを書いています。

# File: app.py 
from bottle import run 
from bottle import Bottle, request, HTTPResponse 

from cassandra.cqlengine import connection 
from cassandra.cqlengine.management import sync_table 

from models import StudentModel 

API = Bottle() 

# Create Connection 
connection.setup(hosts=['192.168.99.100'], 
       default_keyspace='test', 
       protocol_version=3) 

# Sync database table to create table in keyspace 
sync_table(StudentModel) 

@API.get('/students') 
def get_all_students(): 
    all_objs = StudentModel.all() 
    return HTTPResponse(
      body={'data': [x.__json__() for x in all_objs]}, 
      headers={'content-type': 'application/json'}, 
      status_code=200) 

run(host='localhost', 
    port=8080, 
    app=API, 
    server='auto') 

このコードは正常に動作し、私はapiを動作させます。

curl http://localhost:8080/students -i 
HTTP/1.1 200 OK 
Content-Length: 74 
Content-Type: application/json 
Date: Tue, 23 Aug 2016 15:55:23 GMT 
Server: waitress 
Status-Code: 200 

{"data": [{"id": "7f6d18ec-bf24-4583-a06b-b9f55a4dc6e8", "name": "test"}, {"id": "7f6d18ec-bf24-4583-a06b-b9f55a4dc6e9", "name": "test1"}]} 

は今、私はpaggingを追加したい、とlimitoffsetを持っているAPIを作成したいです。

Paging Large Queriesをチェックしますが、例はModelです。

その後、私は私のAPIを変更します。私はhas_more_pagesstart_fetching_next_page()

を使用して、別の解決策を得る

curl "http://localhost:8080/students?limit=1&offset=0" -i 
HTTP/1.1 200 OK 
Content-Length: 74 
Content-Type: application/json 
Date: Tue, 23 Aug 2016 16:12:00 GMT 
Server: waitress 
Status-Code: 200 

{"data": [{"id": "7f6d18ec-bf24-4583-a06b-b9f55a4dc6e8", "name": "test"}]} 

curl "http://localhost:8080/students?limit=1&offset=1" -i 
HTTP/1.1 200 OK 
Content-Length: 75 
Content-Type: application/json 
Date: Tue, 23 Aug 2016 16:12:06 GMT 
Server: waitress 
Status-Code: 200 

{"data": [{"id": "7f6d18ec-bf24-4583-a06b-b9f55a4dc6e9", "name": "test1"}]} 

:として

# File: app.py 
... 
... 
@API.get('/students') 
def get_all_students(): 
    limit = request.query.limit 
    offset = request.query.offset 

    all_objs = StudentModel.all() 
    if limit and offset: 
     all_objs = all_objs[int(offset): int(offset+limit)] 

    return HTTPResponse(
      body={'data': [x.__json__() for x in all_objs]}, 
      headers={'content-type': 'application/json'}, 
      status_code=200) 
... 
... 

とAPIを呼び出します

from bottle import run 
from bottle import Bottle, request, HTTPResponse 

from cassandra.cqlengine import connection 
from cassandra.query import SimpleStatement 
from cassandra.cqlengine.management import sync_table 

from models import StudentModel 

API = Bottle() 

# Create Connection 
connection.setup(hosts=['192.168.99.100'], 
       default_keyspace='test', 
       protocol_version=3) 

# Sync database table to create table in keyspace 
sync_table(StudentModel) 

@API.get('/students') 
def get_all_students(): 
    limit = request.query.limit 
    offset = request.query.offset 

    page = int(request.query.page or 0) 

    session = connection.get_session() 
    session.default_fetch_size = 1 

    objs = StudentModel.all() 

    result = objs._execute(objs._select_query()) 

    data = [] 
    count = 0 
    while (not page or page > count) and result.has_more_pages: 
     count += 1 
     if page and page > count: 
      result.fetch_next_page() 
      continue 

     data.extend(result.current_rows) 
     result.fetch_next_page() 
    all_objs = [StudentModel(**student) for student in data] 

    return HTTPResponse(
      body={'data': [x.__json__() for x in all_objs]}, 
      headers={'content-type': 'application/json'}, 
      status_code=200) 

run(host='localhost', 
    port=8080, 
    app=API, 
    debug=True, 
    server='auto') 

上記の2つのソリューションから、どちらが正しいですか?

答えて

2

現在のところ、CQLEngineでページネーションを行う効率的な方法はありません。 QuerySetスライシングを使用しても、前のページは結果キャッシュで内部的にマテリアライズされることに注意してください。このため、メモリの問題が発生し、要求のパフォーマンスにも影響します。一度に1ページを埋める方法を分析するためのチケットを作成しました。次のチケットを見ることができます:あなたはすぐに効率的なページネーションのサポートが必要な場合は

https://datastax-oss.atlassian.net/browse/PYTHON-627

は、私はcqlengineの代わりにコアドライバを使用することをお勧めします。

+0

ありがとうアラン、あなたはコアドライバのリンクを与えることができますか? – Nilesh

+0

大規模なページングに関するページは次のとおりです:https://datastax.github.io/python-driver/query_paging.html。 次のリリース(3.7)では、paging_stateの実行をまたいでページングを再開できます。 https://datastax-oss.atlassian.net/browse/PYTHON-200 –

+0

アラン、私の質問に同じリンクを付けましたが、私は 'Model'を使ってこれを行う方法を見つけようとしています – Nilesh

関連する問題