Absolutely. The way specified in the DB API (and therefore portable
to other db libraries) is to use cursor.description, which is a tuple
of tuples, documented here:
http://code.google.com/p/pyodbc/wiki/Cursor
The first item in the tuples is the column names, so you can extract
them like so:
cols = [ t[0] for t in cursor.description ]
You could then do something like:
for name, value in zip(cols, row):
print '%s: %s' % (name, value)
I created the Row class to be useful even after the cursor and
connection are closed, so I added the same tuple to all rows as
Row.cursor_description. Apparently I forgot to make the Row wiki
page, but you can see the API documentation by executing help
(pyodbc.Row).
BTW, the Row internals are specially designed to use very little
memory. I use Rows where I would have to create tiny classes or
structs in languages like Java and C/C++. The row names and the
cursor_description are shared by all rows from the same execute call,
so they use less memory than if you created separate objects, one for
each row.