मूल MySQLdb
कर्सर सर्वर से एक बार में संपूर्ण क्वेरी परिणाम प्राप्त करता है। यह बहुत सारी मेमोरी और समय का उपभोग कर सकता है। MySQLdb.cursors.SSCursor का उपयोग करें जब आप एक बड़ी क्वेरी बनाना चाहते हैं और एक समय में सर्वर से परिणाम खींचें।
इसलिए, connect_args={'cursorclass': MySQLdb.cursors.SSCursor}
गुजर जब engine
बनाने का प्रयास करें:
from sqlalchemy import create_engine, MetaData
import MySQLdb.cursors
engine = create_engine('mysql://root:[email protected]/e2', connect_args={'cursorclass': MySQLdb.cursors.SSCursor})
meta = MetaData(engine, reflect=True)
conn = engine.connect()
rs = s.execution_options(stream_results=True).execute()
देखें http://www.sqlalchemy.org/trac/ticket/1089
नोट SSCursor का उपयोग कर तालिका ताले कि लाने पूरा हो गया है जब तक। यह एक ही कनेक्शन का उपयोग कर अन्य कर्सर को प्रभावित करता है: उसी कनेक्शन से दो कर्सर समवर्ती रूप से तालिका से नहीं पढ़ सकते हैं।
हालांकि, अलग-अलग कनेक्शन से कर्सर एक ही तालिका से एक साथ पढ़ सकते हैं।
import MySQLdb
import MySQLdb.cursors as cursors
import threading
import logging
import config
logger = logging.getLogger(__name__)
query = 'SELECT * FROM huge_table LIMIT 200'
def oursql_conn():
import oursql
conn = oursql.connect(
host=config.HOST, user=config.USER, passwd=config.PASS,
db=config.MYDB)
return conn
def mysqldb_conn():
conn = MySQLdb.connect(
host=config.HOST, user=config.USER,
passwd=config.PASS, db=config.MYDB,
cursorclass=cursors.SSCursor)
return conn
def two_cursors_one_conn():
"""Two SSCursors can not use one connection concurrently"""
def worker(conn):
cursor = conn.cursor()
cursor.execute(query)
for row in cursor:
logger.info(row)
conn = mysqldb_conn()
threads = [threading.Thread(target=worker, args=(conn,))
for n in range(2)]
for t in threads:
t.daemon = True
t.start()
# Second thread may hang or raise OperationalError:
# File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 289, in _fetch_row
# return self._result.fetch_row(size, self._fetch_type)
# OperationalError: (2013, 'Lost connection to MySQL server during query')
for t in threads:
t.join()
def two_cursors_two_conn():
"""Two SSCursors from independent connections can use the same table concurrently"""
def worker():
conn = mysqldb_conn()
cursor = conn.cursor()
cursor.execute(query)
for row in cursor:
logger.info(row)
threads = [threading.Thread(target=worker) for n in range(2)]
for t in threads:
t.daemon = True
t.start()
for t in threads:
t.join()
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
two_cursors_one_conn()
two_cursors_two_conn()
ध्यान दें कि oursql अजगर के लिए MySQL बाइंडिंग का एक वैकल्पिक सेट है:
यहाँ कुछ समस्या का प्रदर्शन कोड है। oursql कर्सर सही सर्वर-साइड कर्सर हैं जो fetch rows lazily by default हैं। oursql
इंस्टॉल करके, आप फांसी या एक अपवाद को ऊपर उठाने के बिना
conn = mysqldb_conn()
को
conn = oursql_conn()
तो two_cursors_one_conn()
रन बदलते हैं।
यह MySQL और yield_per के साथ मेरी मेमोरी समस्याओं को ठीक करता है। किसी भी विचार से ट्रैक पर जवाब क्यों कहता है कि यह "बेकार पर" है? – bcoughlan
@bcoughlan: मैंने समसामयिक रूप से एसएसकर्सर्स का उपयोग करने की सीमा के कुछ कोड और चर्चा को जोड़ा है। – unutbu
यह mysqldb के लिए हल होना चाहिए, क्या mysqlconnector के लिए एक समान विकल्प है, क्योंकि मुझे उस ड्राइवर का उपयोग कर एक ही समस्या का सामना करना पड़ रहा है। –