我通过在后端利用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
。
检查它的最佳方法是什么?
答案 0 :(得分:5)
ResultProxy
对象尚未包含任何行。因此,它没有关于它们总量的信息,甚至没有任何信息。 ResultProxy
只是数据库的“指针”。只有在通过ResultProxy
明确获取行时才能获取行。您可以通过迭代此对象,或通过.first()
方法或.fetchall()
方法来实现。
底线:在实际获取所有行并且ResultProxy
对象已耗尽之前,您无法知道其行数。
您可以一次获取所有行并计算它们,然后随意执行任何操作:
rows = result.fetchall()
if len(rows):
# do something with rows
此方法的缺点是我们一次将所有行加载到内存中(rows
是包含所有已获取行的Python list
)。如果获取的行数量非常大和/或您只需要逐个迭代遍历行(通常就是这种情况),这可能是不可取的。
如果一次将所有提取的行加载到内存中是不可接受的,那么我们可以这样做:
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:
...