4

誰かがこれを理解するための例を挙げてください。mysqlのバッファリングされたカーソルは何ですかw.r.t python mysql connector

クエリを実行すると、MySQLCursorBufferedカーソルがサーバーから結果セット全体をフェッチし、その行をバッファします。 バッファ付きカーソルを使用して実行されるクエリの場合、fetchone()などの行取得メソッドは、バッファリングされた行のセットから行を返します。バッファーなしのカーソルの場合、行の取得メソッドが呼び出されるまで、行はサーバーからフェッチされません。この場合、同じ接続で他のステートメントを実行する前に結果セットのすべての行をフェッチする必要があります。そうしないと、InternalError(未読結果が見つかりました)例外が発生します。私はCursorのこれらの2つのタイプが異なる二つの方法を考えることができ

おかげ

答えて

1

最初の方法は、バッファ付きカーソルを使用してクエリを実行すると、返された行の数をMySQLCursorBuffered.rowcountにすることです。ただし、バッファされていないカーソルのrowcount属性は、executeメソッドが呼び出された直後に-1を返します。これは、基本的には、結果セット全体がまだサーバーからフェッチされていないことを意味します。さらに、バッファされていないカーソルの属性は、バッファされたカーソルの行をフェッチするにつれて増加しますが、バッファされたカーソルの属性は、その行からフェッチする際に同じままです。

次のスニペットコードは、上記製のポイントを説明しようとします:

import mysql.connector 


conn = mysql.connector.connect(database='db', 
           user='username', 
           password='pass', 
           host='localhost', 
           port=3306) 

buffered_cursor = conn.cursor(buffered=True) 
unbuffered_cursor = conn.cursor(buffered=False) 

create_query = """ 
drop table if exists people; 
create table if not exists people (
    personid int(10) unsigned auto_increment, 
    firstname varchar(255), 
    lastname varchar(255), 
    primary key (personid) 
); 
insert into people (firstname, lastname) 
values ('Jon', 'Bon Jovi'), 
('David', 'Bryan'), 
('Tico', 'Torres'), 
('Phil', 'Xenidis'), 
('Hugh', 'McDonald') 
""" 

# Create and populate a table 
results = buffered_cursor.execute(create_query, multi=True) 
conn.commit() 

buffered_cursor.execute("select * from people") 
print("Row count from a buffer cursor:", buffered_cursor.rowcount) 
unbuffered_cursor.execute("select * from people") 
print("Row count from an unbuffered cursor:", unbuffered_cursor.rowcount) 

print() 
print("Fetching rows from a buffered cursor: ") 

while True: 
    try: 
     row = next(buffered_cursor) 
     print("Row:", row) 
     print("Row count:", buffered_cursor.rowcount) 
    except StopIteration: 
     break 

print() 
print("Fetching rows from an unbuffered cursor: ") 

while True: 
    try: 
     row = next(unbuffered_cursor) 
     print("Row:", row) 
     print("Row count:", unbuffered_cursor.rowcount) 
    except StopIteration: 
     break 

上記のスニペットは次のように返す必要があります:あなたが見ることができるように、用rowcount属性を

Row count from a buffered reader: 5 
Row count from an unbuffered reader: -1 

Fetching rows from a buffered cursor: 
Row: (1, 'Jon', 'Bon Jovi') 
Row count: 5 
Row: (2, 'David', 'Bryan') 
Row count: 5 
Row: (3, 'Tico', 'Torres') 
Row count: 5 
Row: (4, 'Phil', 'Xenidis') 
Row count: 5 
Row: (5, 'Hugh', 'McDonald') 
Row: 5 

Fetching rows from an unbuffered cursor: 
Row: (1, 'Jon', 'Bon Jovi') 
Row count: 1 
Row: (2, 'David', 'Bryan') 
Row count: 2 
Row: (3, 'Tico', 'Torres') 
Row count: 3 
Row: (4, 'Phil', 'Xenidis') 
Row count: 4 
Row: (5, 'Hugh', 'McDonald') 
Row count: 5 

をバッファされていないカーソルは-1から始まり、生成された結果をループしながら増加します。これは、バッファされたカーソルの場合には当てはまりません。

2つ目の方法は、2つのうちどれが(同じ接続の下で)executeが最初であるかに注意することです。行が完全にフェッチされていないバッファなしカーソルを実行してから、バッファされたカーソルでクエリを実行しようとすると、InternalError例外が発生し、バッファされていないカーソルによって返されたものを消費するかどうかを尋ねられます。以下の説明図である。

import mysql.connector 


conn = mysql.connector.connect(database='db', 
           user='username', 
           password='pass', 
           host='localhost', 
           port=3306) 

buffered_cursor = conn.cursor(buffered=True) 
unbuffered_cursor = conn.cursor(buffered=False) 

create_query = """ 
drop table if exists people; 
create table if not exists people (
    personid int(10) unsigned auto_increment, 
    firstname varchar(255), 
    lastname varchar(255), 
    primary key (personid) 
); 
insert into people (firstname, lastname) 
values ('Jon', 'Bon Jovi'), 
('David', 'Bryan'), 
('Tico', 'Torres'), 
('Phil', 'Xenidis'), 
('Hugh', 'McDonald') 
""" 

# Create and populate a table 
results = buffered_cursor.execute(create_query, multi=True) 
conn.commit() 

unbuffered_cursor.execute("select * from people") 
unbuffered_cursor.fetchone() 
buffered_cursor.execute("select * from people") 

上記断片は、いくつかの未読の結果があることを示すメッセージでInternalError例外が発生します。基本的に言っていることは、同じ接続の下のカーソルで別のクエリを実行するには、バッファされていないカーソルによって返された結果を完全に消費する必要があるということです。 unbuffered_cursor.fetchone()unbuffered_cursor.fetchall()に変更すると、エラーが表示されなくなります。

メモリ消費など他のあまり明白でない違いがあります。バッファー・カーソルは、サーバーから結果セット全体をフェッチして行をバッファーするので、より多くのメモリーを消費する可能性があります。

私はこれが有用であることを望みます。

関連する問題