salamey
salamey

Reputation: 3821

SQLAlchemy query result is None

I have this issue that I don't understand.

I have SELECT() query that returns thousands of rows. For memory issues, I let it return one result row at a time. Then I transform the results to a dict.

select_query = select([table1,table2]).where(all_filters)
res = conn.execute(select_query)
row = res.fetchone()
while row is not None:
    row = res.fetchone()
    print row is None

The results are :

False
False
False
False
True

Why does it still show true even if it should stop when row is None??

So later when I want to create a dict using : row = dict(zip(row.keys(), row)) I get the error : AttributeError: 'NoneType' object has no attribute 'keys'

I'm new to Python, any help would be appreciated.

Upvotes: 0

Views: 4646

Answers (1)

Stefano Sanfilippo
Stefano Sanfilippo

Reputation: 33116

This is not Python-specific, instead it is a property of the while loop in any language. I assume that you are processing the rows inside the loop, so consider this:

row = res.fetchone()
while row is not None:
    row = res.fetchone()
    print row is None
    processRow(row)

During last iteration, res.fetchone() returns None, which is then assigned to row, which becomes None. Then, the processRow statement is executed before the while condition is checked, so it evaluates processRow(None). Only after, during the following iteration, the row is not None condition is false and the loop terminates. There is nothing wrong with this code, it's exactly how it's meant to work.

A possible solution is checking for None before processing, inside the loop:

while True:
    row = res.fetchone()
    if row is None:
        break
    processRow(row)

Or, if the query set is small, you could even fetch them all and process with:

for row in res.fetchall():
    processRow(row)

Upvotes: 1

Related Questions