python에서 행별로 MySQL ResultSet을 가져오는 방법
MySQL ResultSets는 기본적으로 작업을 수행하기 전에 서버에서 완전히 가져옵니다.결과 세트가 큰 경우 이 값은 사용할 수 없게 됩니다.그 대신 서버에서 행을 하나씩 가져오고 싶습니다.
Java에서는 ("ResultSet" 아래)의 지시에 따라 다음과 같은 문장을 작성합니다.
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
이것은 Java에서 잘 동작합니다.질문입니다. 비단뱀에게도 같은 방법이 있을까요?
한 번에 1000줄로 쿼리를 제한하려고 했습니다.이렇게 됩니다.
start_row = 0
while True:
cursor = conn.cursor()
cursor.execute("SELECT item FROM items LIMIT %d,1000" % start_row)
rows = cursor.fetchall()
if not rows:
break
start_row += 1000
# Do something with rows...
단, start_row가 높을수록 속도가 느려지는 것 같습니다.
아니요, 리고아,,를 사용해서fetchone()
fetchall()
아무것도 변하지 않아
설명:
이 문제를 재현하기 위해 사용하는 순진한 코드는 다음과 같습니다.
import MySQLdb
conn = MySQLdb.connect(user="user", passwd="password", db="mydb")
cur = conn.cursor()
print "Executing query"
cur.execute("SELECT * FROM bigtable");
print "Starting loop"
row = cur.fetchone()
while row is not None:
print ", ".join([str(c) for c in row])
row = cur.fetchone()
cur.close()
conn.close()
최대 700,000 행 테이블에서는 이 코드가 빠르게 실행됩니다.그러나 약 9,000,000 행의 테이블에서는 "쿼리 실행 중"이 인쇄된 후 장시간 중단됩니다.그렇기 때문에 이 제품을 사용해도 아무런 차이가 없는 것입니다.fetchone()
★★★★★★★★★★★★★★★★★」fetchall()
.
해야 할 것 요.cursorclass = MySQLdb.cursors.SSCursor
:
MySQLdb.connect(user="user",
passwd="password",
db="mydb",
cursorclass = MySQLdb.cursors.SSCursor
)
커서는 를 한 데이터는 사용하지 않아도 .fetchall
.
집::SSCursor
측 세트를 - 합니다.MySQLdb.cursors
.
mysql이 오프셋을 찾기 위해 행을 다시 검색해야 하므로 한계/오프셋 솔루션은 2차 시간 내에 실행됩니다.예상대로 기본 커서는 클라이언트에 전체 결과 세트를 저장하므로 메모리가 많이 소모될 수 있습니다.
대신 서버 측 커서를 사용하여 쿼리를 계속 실행하고 필요에 따라 결과를 가져올 수 있습니다.커서 클래스는 연결 호출 자체에 기본값을 지정하거나 매번 커서 메서드에 클래스를 지정함으로써 맞춤화할 수 있습니다.
from MySQLdb import cursors
cursor = conn.cursor(cursors.SSCursor)
하지만 그게 전부는 아니다.mysql 결과를 저장할 뿐만 아니라 기본 클라이언트 측 커서가 실제로 모든 행을 가져옵니다.이 동작은 문서화되어 있지 않기 때문에 매우 유감입니다.즉, 모든 행에 대해 완전한 python 객체가 생성되어 원래 mysql 결과보다 훨씬 더 많은 메모리가 소비됩니다.
대부분의 경우 클라이언트에 저장된 결과를 반복기로 포장하면 적절한 메모리 사용률로 최상의 속도를 얻을 수 있습니다.하지만 그걸 원하시면 직접 굴리셔야 합니다.
이 버전의 페톤을 먹어봤어?아니면 다른 거?
row = cursor.fetchone()
while row is not None:
# process
row = cursor.fetchone()
그리고 이거 먹어봤어?
row = cursor.fetchmany(size=1)
while row is not None:
# process
row = cursor.fetchmany( size=1 )
모든 드라이버가 이러한 기능을 지원하는 것은 아니기 때문에 오류가 발생하거나 속도가 너무 느릴 수 있습니다.
편집.
실행 중이면 데이터베이스를 기다리는 것입니다.이것은 Python을 한 줄씩 나열하는 것이 아니라 MySQL입니다.
MySQL은 자체 캐시 관리의 일부로 모든 행을 가져오는 것을 선호합니다.이것은 Integer의 fetch_size를 지정함으로써 비활성화됩니다.MIN_VALUE(-2147483648L).
문제는 Python DBAPI의 어떤 부분이 JDBC fetch_size와 동등해지는가 하는 것입니다.
커서의 배열 크기 특성일 수 있습니다.해라
cursor.arraysize=-2**31
또한 MySQL이 결과 세트를 캐싱하는 대신 스트리밍해야 하는지 확인합니다.
MySQLdb.cursors를 사용해 보겠습니다.SSDict Cursor
con = MySQLdb.connect(host=host,
user=user,
passwd=pwd,
charset=charset,
port=port,
cursorclass=MySQLdb.cursors.SSDictCursor);
cur = con.cursor()
cur.execute("select f1, f2 from table")
for row in cur:
print row['f1'], row['f2']
나는 다른 대답들과 약간 섞여서 가장 좋은 결과를 찾았다.
여기에는 설정이 포함되어 있습니다.cursorclass=MySQLdb.cursors.SSDictCursor
(MySQLdb의 경우) 또는pymysql.cursors.SSDictCursor
(PyMySQL의 경우)를 연결 설정의 일부로 사용합니다.그러면 서버가 쿼리/결과('SS'는 결과를 가져오는 기본 커서가 아닌 서버 측을 의미)를 유지하고 각 행에서 사전을 빌드할 수 있습니다(예: {'id': 1, '이름': '쿠키 몬스터').
그리고 행을 루프하기 위해 Python 2.7과 3.4에 무한 루프가 발생했습니다.while rows is not None
왜냐하면cur.fetchmany(size=10000)
호출되어 남은 결과가 없습니다.메서드는 빈 목록을 반환했습니다( ).[]
(없음)이 아닌 )을 클릭합니다.
실제 예:
query = """SELECT * FROM my_table"""
conn = pymysql.connect(host=MYSQL_CREDENTIALS['host'], user=MYSQL_CREDENTIALS['user'],
passwd=MYSQL_CREDENTIALS['passwd'], charset='utf8', cursorclass = pymysql.cursors.SSDictCursor)
cur = conn.cursor()
results = cur.execute(query)
rows = cur.fetchmany(size=100)
while rows:
for row in rows:
process(row)
rows = cur.fetchmany(size=100)
cur.close()
conn.close()
언급URL : https://stackoverflow.com/questions/337479/how-to-get-a-row-by-row-mysql-resultset-in-python
'programing' 카테고리의 다른 글
Python의 진입점에 대해 설명하시겠습니까? (0) | 2022.10.26 |
---|---|
다음 주 월요일, 화요일 등의 날짜를 가져옵니다. (0) | 2022.10.26 |
time_t는 어떤 원시 데이터 유형입니까? (0) | 2022.10.26 |
클래스 스타일 또는 데코레이터 구문을 사용하지 않고 mapGetters, mapActions Vuex 및 typescript의 인텔리센스를 얻는 방법 (0) | 2022.10.26 |
javascript 파일 이름 짓기 규칙은 무엇입니까? (0) | 2022.10.26 |