<div dir="ltr"><div><div>I'm writing a DBAPI module for a custom database wrapper. The way I get data from a query is to ask the underlying database it for a chunk of rows, at which point it spits out an unpredictable number (it's a black box to me).</div>

<div><br></div><div>I'm trying to figure out how to implement cursor.fetchmany on top of this, and make it as efficient as possible. There are two limiting cases:</div><div><ol><li>Python caller asks for the next 10 rows, but the DB gives the next 100 rows. Obviously, I just cache the extra rows in this case.</li>

<li>Python caller asks for the next 100 rows, but the next call to the DB only gives me 10 rows.</li></ol>In case (2), PEP-249 seems to be telling me that I should keep calling the DB to get more rows:</div></div><div><br>

</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">The number of rows to fetch per call is specified by the parameter. If it is not given, the cursor's arraysize determines the number of rows to be fetched. <b>The method should try to fetch as many rows as indicated by the size parameter</b>. If this is not possible due to the specified number of rows not being available, fewer rows may be returned.<br>

<br></blockquote>However, I'd rather implement it slightly differently: "... fetch as many rows as possible without incurring multiple calls to the underlying DB engine, but no more than indicated by the size parameter."<div>

<div><br></div><div>Having a loop to make multiple DB calls hidden in the DBAPI module, rather than in the client code, strikes me as a bad approach because it adds extra unpredictable latency. A properly-written client will have to do some looping anyway:</div>

<div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="courier new, monospace"># client code to get next 10k rows from the cursor</font></div><div><font face="courier new, monospace"><br>

</font></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="courier new, monospace">rows = []<br>while True:<br></font><span style="font-family:'courier new',monospace">    # PEP-249 says that fetchmany should do its best to get as many rows as requested<br>

</span></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="courier new, monospace">    # ... but that will mean a similar or identical loop in the DBAPI module<br><br>    more_rows = cur.fetchmany(len(rows) - 10000)<br>

    if not more_rows:<br>        break<br>    else:<br>        rows += more_rows<br></font></blockquote><div><br></div>What do you think? Is there some good reason to adhere strictly to PEP-249?</div></div><div><br></div>

<div>Thanks,</div><div>Dan</div></div>