。
最初の方法は、バッファ付きカーソルを使用してクエリを実行すると、返された行の数を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()
に変更すると、エラーが表示されなくなります。
メモリ消費など他のあまり明白でない違いがあります。バッファー・カーソルは、サーバーから結果セット全体をフェッチして行をバッファーするので、より多くのメモリーを消費する可能性があります。
私はこれが有用であることを望みます。