有人能举个例子来理解这一点吗?
执行查询后,MySQLCursorBuffered游标从服务器获取整个结果集并缓冲行。对于使用缓冲游标执行的查询,行取取方法(如set ())从缓冲行集返回行。对于非缓冲游标,在调用行取方法之前,不会从服务器获取行。在这种情况下,必须确保在同一连接上执行任何其他语句之前获取结果集的所有行,否则将引发InternalError (未读取结果发现)异常。
谢谢
发布于 2017-11-27 01:24:25
我认为这两种类型的Cursor是不同的。
第一种方法是,如果使用缓冲游标执行查询,则可以通过检查MySQLCursorBuffered.rowcount获得返回的行数。但是,未缓冲游标的rowcount属性在调用execute方法后立即返回execute。这基本上意味着尚未从服务器获取整个结果集。此外,当您从非缓冲游标中提取行时,它的rowcount属性会增加,而缓冲游标的rowcount属性在从它获取行时保持不变。
下面的代码片段试图说明上面提出的要点:
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上面的片段应该返回如下内容:
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如您所见,未缓冲游标的rowcount属性从-1开始,并在循环其生成的结果时增加。缓冲游标的情况并非如此。
区分区别的第二种方法是注意两个(在相同连接下)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(),错误将消失。
还有其他不太明显的差别,比如内存消耗。缓冲游标可能会消耗更多内存,因为它们可以从服务器获取结果集并缓冲行。
我希望这证明是有用的。
https://stackoverflow.com/questions/46682012
复制相似问题