title: SQLAlchemy cursors: AttributeError: 'tuple' object has no attribute 'items'
body: <p>I'm attempting to write an iterator to take in a query and export rows in batches as a list of dicts. Here's a complete example of what I'm working with:</p>
  
  <pre class="lang-py prettyprint-override"><code>class QueryStream(collections.Iterator):
      def __init__(self, conn_details, query, max_rows=None, batch_size=2000):
          # Initialize vars.
          self.engine = dst.get_connection(conn_details)
          self.query = query
          self.max_rows = max_rows
          self.batch_size = batch_size
          self.fetched_rows = 0
  
          # Create a database cursor from query.
          self.conn = self.engine.raw_connection()
          self.cursor = self.conn.cursor()
          self.cursor.execute(self.query)
  
      def next(self):
          try:
              if self.max_rows:
                  if self.max_rows &lt;= self.fetched_rows:
                      # Maximum rows has been fetched, so stop iterating.
                      raise StopIteration
                  elif self.max_rows &lt;= self.batch_size:
                      # Max rowset is small enough to be done in one batch.
                      batch_size = self.max_rows
                  elif self.max_rows - self.fetched_rows &lt; self.batch_size:
                      # On the final batch, must fetch only remaining rows.
                      batch_size = self.max_rows - self.fetched_rows
              else:
                  # Get default batch size.
                  batch_size = self.batch_size
  
              batch = [dict(row.items()) for row in self.cursor.fetchmany(batch_size)]
              if len(batch):  # 0 rows were returned, so we're probs at the end.
                  self.fetched_rows += len(batch)
                  print('Fetch {} rows so far.'.format(repr(self.fetched_rows)), file=sys.stderr)
                  return batch
              else:
                  raise StopIteration
          except StopIteration:
              self.cursor.close()
              self.conn.close()
              self.engine.dispose()
              raise StopIteration
  
  </code></pre>
  
  <p>The problem is this line:</p>
  
  <pre class="lang-py prettyprint-override"><code>batch = [dict(row.items()) for row in self.cursor.fetchmany(batch_size)]
  </code></pre>
  
  <p>throws this error:</p>
  
  <p><code>AttributeError: 'tuple' object has no attribute 'items'</code></p>
  
  <p>I was under the impression that a <code>RowProxy</code> object would be returned for every result in the result set, which supports <a href="https://docs.sqlalchemy.org/en/13/core/connections.html#sqlalchemy.engine.RowProxy.items" rel="nofollow noreferrer">dict-like operations</a> (as is mentioned in <a href="https://stackoverflow.com/a/50141868/2809495">this post</a>), but it appears the results are just plain tuples. The SQLAlchemy docs are not 100% clear on what the expected type of the results from a cursor is, only offering <a href="https://docs.sqlalchemy.org/en/13/core/connections.html#multiple-result-sets" rel="nofollow noreferrer">this example</a> of usage.</p>
  
  <p>Question: Am I doing something wrong with my cursor usage? I need the results to be a list of dicts with column names as keys, but I don't know if that's possible without having <code>RowProxy</code> instead of tuples.</p>