简体   繁体   中英

Check if <sqlalchemy.engine.result.ResultProxy> object is empty

I'm downloading some data from a SQL Server database through a library that leverages pymssql in the back-end. The result of a curson.execute("""<QUERY BODY>""") is a sqlalchemy.engine.result.ResultProxy object. How can I check if the result of the query was empty, so there are no rows?

cur = ff.sql.create_engine(server=dw.address, db=dw.BI_DW,
                               login=":".join([os.environ["SQL_USER"],
                                               os.environ["SQL_PASSWD"]]))
for n in range(100):
    result = cur.execute("""QUERY BODY;""")
    if result:
        break

Unfortunately, result will never be None even when no rows were returned by the SQL query.

What's the best way to check for that?

The ResultProxy object does not contain any rows yet. Therefore it has no information about the total amount of them, or even whether there are any. ResultProxy is just a "pointer" to the database. You get your rows only when you explicitly fetch them via ResultProxy . You can do that via iteration over this object, or via .first() method, or via .fetchall() method.

Bottom line : you cannot know the amount of fethced rows until you actually fetch all of them and the ResultProxy object is exhausted.

Approach #1

You can fetch all the rows at once and count them and then do whatever you need with them:

rows = result.fetchall()
if len(rows):
    # do something with rows

The downside of this method is that we load all rows into memory at once ( rows is a Python list containing all the fetched rows). This may not be desirable if the amount of fetched rows is very large and/or if you only need to iterate over the rows one-by-one independently (usually that's the case).

Approach #2

If loading all fetched rows into memory at once is not acceptable, then we can do this:

rows_amount = 0
for row in result:
    rows_amount += 1
    # do something with row
if not rows_amount:
    print('There were zero rows')
else:
    print('{} rows were fetched and processed'.format(rows_amount))

SQLAlchemy < 1.2: You can always turn the ResultProxy into an iterator:

res = engine.execute(...)
rp_iter = iter(res)
row_count = 0
try:
    row = next(rp_iter)
    row_count += 1
except StopIteration:
    # end of data
    if not row_count:
      # no rows returned, StopIteration was raised on first attempt

In SQLAlchemy >= 1.2, the ResultProxy implements both .next() and .__next__() , so you do not need to create the iterator:

res = engine.execute()
row_count = 0
try:
    row = next(res)
    row_count += 1
except StopIteration:
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM