I like what @LittleNyima has shared. In addition to that, you can also execute the query multiple times with LIMIT and OFFSET if the solution allows it.
def generate_dataset(cursor, limit=1000, offset=200):
query_with_limit = query + f" LIMIT {limit} OFFSET {offset}"
cursor.execute(query_with_limit)
rows = cursor.fetchall()
if not rows:
return tuple()
else:
for row in rows:
# some transformation
yield tuple_version_of_row