检查<sqlalchemy.engine.result.resultproxy>对象是否为空

时间:2016-06-08 10:49:02

标签: python sqlalchemy

我通过在后端利用pymssql的库从SQL Server数据库下载一些数据。 curson.execute("""<QUERY BODY>""")的结果是sqlalchemy.engine.result.ResultProxy个对象。如何检查查询结果是否为空,因此没有行?

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

不幸的是,即使SQL查询没有返回任何行,result也永远不会是None

检查它的最佳方法是什么?

2 个答案:

答案 0 :(得分:5)

ResultProxy对象尚未包含任何行。因此,它没有关于它们总量的信息,甚至没有任何信息。 ResultProxy只是数据库的“指针”。只有在通过ResultProxy明确获取行时才能获取行。您可以通过迭代此对象,或通过.first()方法或.fetchall()方法来实现。

底线:在实际获取所有行并且ResultProxy对象已耗尽之前,您无法知道其行数。

方法#1

您可以一次获取所有行并计算它们,然后随意执行任何操作:

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

此方法的缺点是我们一次将所有行加载到内存中(rows是包含所有已获取行的Python list)。如果获取的行数量非常大和/或您只需要逐个迭代遍历行(通常就是这种情况),这可能是不可取的。

方法#2

如果一次将所有提取的行加载到内存中是不可接受的,那么我们可以这样做:

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))

答案 1 :(得分:0)

SQLAlchemy <1.2:您始终可以将ResultProxy变成迭代器:

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

SQLAlchemy >= 1.2, the ResultProxy implements both .next() and .__next__()中,因此您无需创建迭代器:

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