@@ -139,17 +139,78 @@ provided by asyncpg supports *asynchronous iteration* via the ``async for``
139139statement, and also a way to read row chunks and skip forward over the
140140result set.
141141
142+ To iterate over a cursor using a connection object use
143+ :meth: `Conection.cursor() <asyncpg.connection.Connection.cursor> `.
144+ To make the iteration efficient, the cursor will prefetch records to
145+ reduce the number of queries sent to the server:
146+
147+ .. code-block :: python
148+
149+ async def iterate (con : Connection):
150+ async with con.transaction():
151+ # Postgres requires non-scrollable cursors to be created
152+ # and used in a transaction.
153+ async for record in con.cursor(' SELECT generate_series(0, 100)' ):
154+ print (record)
155+
156+ Or, alternatively, you can iterate over the cursor manually (cursor
157+ won't be prefetching any rows):
158+
159+ .. code-block :: python
160+
161+ async def iterate (con : Connection):
162+ async with con.transaction():
163+ # Postgres requires non-scrollable cursors to be created
164+ # and used in a transaction.
165+
166+ async with con.transaction():
167+ # Create a Cursor object
168+ cur = await con.cursor(' SELECT generate_series(0, 100)' )
169+
170+ # Move the cursor 10 rows forward
171+ await cur.forward(10 )
172+
173+ # Fetch one row and print it
174+ print (await cur.fetchrow())
175+
176+ # Fetch a list of 5 rows and print it
177+ print (await cur.fetch(5 ))
178+
179+ It's also possible to create cursors from prepared statements:
180+
181+ .. code-block :: python
182+
183+ async def iterate (con : Connection):
184+ # Create a prepared statement that will accept one argument
185+ stmt = await con.prepare(' SELECT generate_series(0, $1)' )
186+
187+ async with con.transaction():
188+ # Postgres requires non-scrollable cursors to be created
189+ # and used in a transaction.
190+
191+ # Execute the prepared statement passing `10` as the
192+ # argument -- that will generate a series or records
193+ # from 0..10. Iterate over all of them and print every
194+ # record.
195+ async for record in stmt.cursor(10 ):
196+ print (record)
197+
198+
142199 .. note ::
143200
144- Cursors created by a call to :meth: `PreparedStatement.cursor() ` are
145- *non-scrollable *: they can only be read forwards. To create a scrollable
201+ Cursors created by a call to
202+ :meth: `Conection.cursor() <asyncpg.connection.Connection.cursor> ` or
203+ :meth: `PreparedStatement.cursor() <asyncpg.prepared_stmt.PreparedStatement.cursor> `
204+ are *non-scrollable *: they can only be read forwards. To create a scrollable
146205 cursor, use the ``DECLARE ... SCROLL CURSOR `` SQL statement directly.
147206
148207.. warning ::
149208
150- Cursors created by a call to :meth: `PreparedStatement.cursor() `
151- cannot be used outside of a transaction. Any such attempt will result
152- in :exc: `~asyncpg.exceptions.InterfaceError `.
209+ Cursors created by a call to
210+ :meth: `Conection.cursor() <asyncpg.connection.Connection.cursor> ` or
211+ :meth: `PreparedStatement.cursor() <asyncpg.prepared_stmt.PreparedStatement.cursor> `
212+ cannot be used outside of a transaction. Any such attempt will result in
213+ :exc: `~asyncpg.exceptions.InterfaceError `.
153214
154215 To create a cursor usable outside of a transaction, use the
155216 ``DECLARE ... CURSOR WITH HOLD `` SQL statement directly.
0 commit comments