따라서 yield 키워드를 사용하거나 반복문 내에서 item을 하나하나 꺼내와서 사용할 수 있다.
result_iter = User.scan(limit=100, filter_condition=User.phone_number.startswith("+82") data =[data asyncfor data in result_iter]print(len(data))print(result_iter.total_count) assert len(data)== result_iter.total_count
주의할점은, 결과집합의 total_count나 last_evaluated_key값을 제대로 받아오려면,
data =[data asyncfor data in result_iter]
위 코드처럼 ResultIterator를 반복문으로 돌려주고 나서 total_count나 last_evaluated_key 연산을 해올 수 있다.
scan한 결과의 result_iter를 바로 받아서 total_count나 last_evaluated_key에 접근하려고 하면 각각 0, None을 리턴할 것이니
사용할 때 꼭 ResultIterator를 반복문으로 모두 돌려준뒤 사용하자.
2) filter_condition
테이블에서 데이터를 스캔해올 때, 특정 검색 조건을 걸어 스캔하는 옵션이다.
형식은 pynamoDB에서는 {ModelClass}.{attrubute_name}.{condition} 와 같이 사용한다.
아래는 예시 Model 클래스인 User 클래스이다.
(pynamoDB의 모델로써 클래스를 사용하려면 아래처럼 pynamodb.Model을 상속받아야 한다.)
DynamoDB에서 scan을 사용할 때, 병렬로 여러 개의 스캔단위를 돌릴 수 있도록 사용할 수 있는 개념이 segment이다.
DynamoDB에서 한번에 많은 양의 데이터를 스캔하려고 할 때 아래와 같이 몇가지 문제점이 발생할 수 있다.
스캔할 테이블 또는 인덱스가 클수록 Scan을 완료하는 데 걸리는 시간이 늘어납니다. 또한 순차적 Scan은 프로비저닝된 읽기 처리량 용량을 항상 최대한 사용할 수 있는 것은 아닙니다. DynamoDB가 여러 물리적 파티션 간에 라지 테이블 데이터를 분산해도 Scan 작업은 한 번에 한 파티션만 읽을 수 있습니다. 이러한 이유로 Scan의 처리량은 단일 파티션의 최대 처리량에 따라 제약을 받습니다.
TOTAL_SEGMENT=10 futures =[]for segment inrange(TOTAL_SEGMENT): # future는 아직 코드(scan 작업)가 수행되지 않은 coroutine 객체를 담는다. future = User.scan( filter_condition=User.phone_number.startswith("+82"), segment=segment, total_segment=TOTAL_SEGMENT) futures.append(future)) # futures에 담긴 coroutine 리스트가 각각 동시에 수행되어 segment_result_list 변수에 저장된다. segment_result_list =await asyncio.gather(*futures)
4) last_evaluated_key
위의 segment에서는 많은 양의 데이터를 병렬로 scan 작업을 하기 위해 사용하기 위해 사용했다면,
last_evaluated_key는 DynamoDB에서 한번에 스캔할 수 있는 데이터의 크기가 1MB로 한정되어있기 때문에,
pagination을 설정하여 많은 양의 데이터를 순차적으로 가져올 수 있는 기능이다. pagination을 위해 보통 limit 옵션과 함께 쓰인다.
아래의 예시 코드를 보자.
last_evaluated_key = None while True: result_iter =await User.scan(last_evaluated_key=last_evaluated_key, limit=100) data =[data asyncfor data in result_iter] last_evaluated_key =await result_iter.last_evaluated_key if last_evaluated_key is None:break
위 코드를 보면,
첫번째 반복문에서 result_iter에 담긴 item의 수는 limit을 100개로 지정했으므로 100개의 아이템만 저장이 되어있다.
만약 전체 아이템의 갯수가 1000개일 경우,
0~99번째 인덱스의 User Model 객체 데이터들이 data 변수에 담기게 된다.
data 변수에 각 Model을 할당한 후, last_evaluated_key를 읽어오면, 99번째 User Model 객체의
hash_key, range_key 정보가 last_evaluated_key 변수에 담긴다.
(last_evaluated_key는 아래와 같이 hash_key, range_key 형식이다.)
댓글 영역