2016-08-23 2 views
0

으로 모델이 있습니다.RAND API를 사용한 카산드라 모델 호출

# 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를 변경합니다

# 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를 호출 :

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"}]} 

내가 has_more_pagesstart_fetching_next_page()

를 사용하여 다른 솔루션을 얻을
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 슬라이싱을 사용하면 이전 페이지가 여전히 결과 캐시에서 내부적으로 구체화됩니다. 따라서 메모리 문제가 발생할 수 있으며 요청 성능에도 영향을줍니다. 한 번에 한 페이지를 채울 방법을 분석 할 수있는 티켓을 만들었습니다. 다음 표를 볼 수 있습니다 : 당신이 즉시 효율적인 매김 지원이 필요한 경우

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

, 나는 cqlengine 대신 핵심 드라이버를 사용하는 것이 좋습니다.

+0

감사합니다. Alan, 코어 드라이버에 대한 링크를 제공 할 수 있습니까? – Nilesh

+0

큰 쿼리를 페이징하는 방법에 대한 몇 가지 문서가 있습니다 : https://datastax.github.io/python-driver/query_paging.html. 다음 릴리스 (3.7)에서는 paging_state 실행을 통해 페이징을 재개 할 수 있습니다. https://datastax-oss.atlassian.net/browse/PYTHON-200 –

+0

앨런, 내 질문에 동일한 링크를 제공했지만 모델을 사용하여이 작업을 수행하려고합니다. – Nilesh