简体   繁体   English

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

[英]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.我正在通过一个在后端利用pymssql的库从 SQL Server 数据库下载一些数据。 The result of a curson.execute("""<QUERY BODY>""") is a sqlalchemy.engine.result.ResultProxy object.一的结果curson.execute("""<QUERY BODY>""")是一个sqlalchemy.engine.result.ResultProxy对象。 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.不幸的是,即使 SQL 查询没有返回任何行, result也永远不会是None

What's the best way to check for that?检查的最佳方法是什么?

The ResultProxy object does not contain any rows yet. ResultProxy对象还不包含任何行。 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. ResultProxy只是一个指向数据库的“指针”。 You get your rows only when you explicitly fetch them via ResultProxy .只有当您通过ResultProxy显式获取行时,您才能获取行。 You can do that via iteration over this object, or via .first() method, or via .fetchall() method.你可以做到这一点通过迭代过这个对象,或通过.first()方法,或通过.fetchall()方法。

Bottom line : you cannot know the amount of fethced rows until you actually fetch all of them and the ResultProxy object is exhausted.底线:在您实际获取所有行并且ResultProxy对象耗尽之前,您无法知道 fethced 行的数量。

Approach #1方法#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).这种方法的缺点是我们一次将所有行加载到内存中( rows是一个包含所有获取行的 Python list )。 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方法#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: 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

In SQLAlchemy >= 1.2, the ResultProxy implements both .next() and .__next__() , so you do not need to create the iterator:SQLAlchemy >= 1.2 中, ResultProxy 实现了.next().__next__() ,所以你不需要创建迭代器:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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