2013-04-11 3 views
1

데이터베이스 (단일 테이블)의 결과를 쿼리하는 작은 프로그램을 작성하고 있습니다. 파이썬 3.3, sqlalchemy 및 postgres 데이터베이스를 사용하고 있습니다.하나씩 데이터베이스에서 결과 가져 오기

result = db_session.query(Data).all() 
progress = 0 
for row in result: 
    update_progress_bar(progress, len(result)) 
    do_something_with_data(row) 
    progress += 1 

변수 '결과'에는 수천 개의 행이 포함되며 데이터 처리에는 다소 시간이 걸립니다. 그래서 간단한 진도 표시 줄을 도입하여 병사가 어떻게 걸릴지 생각해보십시오. 문제는 전체 시간의 30 %가 데이터베이스를 큐잉한다는 것입니다 (첫 번째 줄). 그래서 프로그램을 시작할 때 진행 막대가 움직이기 전에 나는 커다란 지체를 갖습니다. 또한 모든 결과를 기억할 필요가 없습니다. 별도로 처리 할 수 ​​있습니다.

모든 프로그램을 메모리에로드하지 않고 모든 행을 수신 할 때까지 하나씩 행을 얻으려면 위의 프로그램을 수정할 방법이 있습니까? 또한 데이터 쿼리 및 처리 진행 상황을 모니터링하고 싶습니다. ,

for row in db_session.query(Data).yield_per(10): 
    do_something_with_data(row) 

.all() 참으로 목록 로 설정 한 전체 결과를집니다 :

+0

EOL sugestion 덕분에 '스트리밍 결과'를 살펴볼 수 있습니다. 작동 시키려면 ".execution_options (stream_results = True)"를 사용하여 쿼리를 실행해야합니다. 나는 또한 내 데이터베이스 어댑터 (pypostgresql) 스트리밍을 지원하지 않는 것을 알게됩니다. 그 일을 할 수있는 유일한 사람은 psycop2입니다. 운 좋게도, 새로운 psycop2 2.5는 이제 python 3.3을 지원합니다. :) 경험을 공유하고 테스트 해 보겠습니다. – Marek

답변

3

당신은 배치 크기를 설정 .all(), 전화 .yield_per()를 호출없이 쿼리 이상 단지 루프에 필요 결과 집합이 클 경우 지연이 발생합니다. 데이터베이스 API가을 제공하는 경우 .yield_per()을 설정 한 후 쿼리를 직접 반복하여 필요한 결과를 가져 오는 대신 을 가져옵니다.

당신은 선행 많은 행이 반환되는 방법을 먼저 .count() 전화를 알고 싶어하는 경우 :

result = db_session.query(Data) 
count = result.count() 

for row in result.yield_per(10): 
    update_progress_bar(progress, count) 
    do_something_with_data(row) 
    progress += 1 

.count() 먼저 우리를 위해 계산 우리에게 항목을 제공 할 수있는 데이터베이스 요청합니다.

데이터베이스는 여전히 일 수 있으며 결과 행을 사전 캐싱해야하므로 .yield_per()을 사용하는 경우에도 시작 지연이 발생할 수 있습니다. 이 경우 windowed query을 사용하여 열의 의 값 범위를 기반으로 블록으로 쿼리를 분할해야합니다. 웨더 여부는 정확한 테이블 레이아웃에 따라 다릅니다.

+1

필요에 따라 결과를 가져 오는 iterator에 대한 참조가 있습니까? 내가 올바르게 기억한다면 스트리밍을 지원하는 DBAPI는 많지 않으며 특히 Sqlite3은 모든 행을 주먹으로 가져옵니다. – EOL

+0

불행히도 프로그램이 메인 루프에 도달하기 전에는 여전히 지연이 발생합니다. PostgreSQL을 사용하고 있습니다. – Marek

+0

@Marek : 데이터베이스 * 자체는 데이터 시작을 시작하기 전에 시작 시간을 쉽게 요구할 수 있습니다. 또한 데이터베이스 API 자체가 스트리밍을 지원하지 않을 수도 있습니다. '.all()'*을 사용하면 모든 것을 처음으로 메모리에로드하고, 쿼리를 반복하면 기본 데이터베이스 API에 일괄 적으로 결과를 줄 수있는 * 기회 *가 제공됩니다. –

관련 문제