3

Say I have a MySQL table I access through MySQLDB. I have a standard

SELECT statement:
sql = "SELECT * FROM EMPLOYEE \
       WHERE INCOME > '%d'" % (1000)

I then execute it with the cursor and pluck out the columns as below.

   cursor.execute(sql)
   results = cursor.fetchall()
   for row in results:
      fname = row[0]
      lname = row[1]
      age = row[2]
      sex = row[3]
      income = row[4]

Is it possible to assign all the column names in a single statement? Something like:

for row in results:
    fname, lname, age, sex, income = unpack(row)

I could always do:

fname, lname, age, sex, income = row[0], row[1], row[2], row[3], row[4]

But I have over 30 columns in my table and this is getting painful. Note that though I'm using MySQL right now, I'd like this to be as DB agnostic as possible; our benevolent overlords might decide to port everything over to another database at any point.

Craig
  • 1,929
  • 5
  • 30
  • 51
  • You should remove references to SQL in your question, since it's really irrelevant. You have an array you want to deconstruct; it doesn't matter how you got the data. – Carcigenicate Aug 19 '16 at 14:20
  • why do you not simply write `for fname, lname, age, sex, income in results:`? – njzk2 Aug 19 '16 at 14:20
  • 1
    You might want to reconsider `SELECT *` if you're expecting a fixed number and order of columns, if the table layout changes you'll break things. – Mark Ransom Aug 19 '16 at 14:22
  • you can even consider running a `PRAGMA table_info()` query on the table to get a look at the number of columns and header names – Ma0 Aug 19 '16 at 14:34

3 Answers3

5

Just do:

fname, lname, age, sex, income = row

if len(row)==5 it should works, otherwise, if you have python 3 you can use extended iterable unpacking

fname, lname, age, sex, income, *other = row

other will be a list of all remaining elements.

If you have python 2: You can use a small function as in this answer:

def unpack_list(a, b, c, d, e, *f):
    return a, b, c, d, e, f

fname, lname, age, sex, income, other = unpack_list(*row)

If you only want the 5 first elements, as @Ev.Kounis meant, you can do:

fname, lname, age, sex, income = row[:5]
Community
  • 1
  • 1
jrjc
  • 21,103
  • 9
  • 64
  • 78
  • you can also add an asterisk to any of those (preferably the last) to make sure that even if there are more, execution will go on. Slicing `row` would also be an option since it doesnt throw errors when e.g., `[1,2,3][:5]` – Ma0 Aug 19 '16 at 14:24
  • @Ev.Kounis I edited, but I believe it's python 3 only. – jrjc Aug 19 '16 at 14:27
  • `fname, lname, age, sex, income = row[:5]` works in both Python 2 and 3. – vaultah Aug 19 '16 at 14:41
1

How about an entirely different approach?

You could use a DictCursor and reference things by name. E.g,

cursor = db.cursor(MySQLdb.cursors.DictCursor)
cursor.execute(sql)
results = cursor.fetchall()
for row in results:
    function_with_fname(row['fname'])
    function_with_age(row['age'])
Paul H
  • 65,268
  • 20
  • 159
  • 136
0
results = [[1,2,3,4,5],
['a', 'b', 'c', 'd', 'e'],
[True, False, True, False, True]
]

for one, two, three, four, five in results:
    print one, two, three, four, five
>>> 1 2 3 4 5
>>> a b c d e
>>> True False True False True

You could also unpack the values in your for loop itself.

ospahiu
  • 3,465
  • 2
  • 13
  • 24