diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2021-11-02 21:42:05 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2021-11-02 21:42:05 +0000 |
| commit | 37bc1285c5bddf1e1b3a5830c530139e6fdd4bc4 (patch) | |
| tree | d9ba2604cbc02d2fb43b737adc4a80c3b54e2f33 /test/sql/test_resultset.py | |
| parent | 72780bae3377c45abb03cb62b638b84ed04375e2 (diff) | |
| parent | 33824a9c06ca555ad208a9925bc7b40fe489fc72 (diff) | |
| download | sqlalchemy-37bc1285c5bddf1e1b3a5830c530139e6fdd4bc4.tar.gz | |
Merge "ensure soft_close occurs for fetchmany with server side cursor" into main
Diffstat (limited to 'test/sql/test_resultset.py')
| -rw-r--r-- | test/sql/test_resultset.py | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/test/sql/test_resultset.py b/test/sql/test_resultset.py index 86aa15f26..346cb3d58 100644 --- a/test/sql/test_resultset.py +++ b/test/sql/test_resultset.py @@ -2736,6 +2736,68 @@ class AlternateCursorResultTest(fixtures.TablesTest): # buffer of 98, plus buffer of 99 - 89, 10 rows eq_(len(result.cursor_strategy._rowbuffer), 10) + @testing.combinations(True, False, argnames="close_on_init") + @testing.combinations( + "fetchone", "fetchmany", "fetchall", argnames="fetch_style" + ) + def test_buffered_fetch_auto_soft_close( + self, connection, close_on_init, fetch_style + ): + """test #7274""" + + table = self.tables.test + + connection.execute( + table.insert(), + [{"x": i, "y": "t_%d" % i} for i in range(15, 30)], + ) + + result = connection.execute(table.select().limit(15)) + assert isinstance(result.cursor_strategy, _cursor.CursorFetchStrategy) + + if close_on_init: + # close_on_init - the initial buffering will exhaust the cursor, + # should soft close immediately + result = result.yield_per(30) + else: + # not close_on_init - soft close will occur after fetching an + # empty buffer + result = result.yield_per(5) + assert isinstance( + result.cursor_strategy, _cursor.BufferedRowCursorFetchStrategy + ) + + with mock.patch.object(result, "_soft_close") as soft_close: + if fetch_style == "fetchone": + while True: + row = result.fetchone() + + if row: + eq_(soft_close.mock_calls, []) + else: + # fetchone() is also used by first(), scalar() + # and one() which want to embed a hard close in one + # step + eq_(soft_close.mock_calls, [mock.call(hard=False)]) + break + elif fetch_style == "fetchmany": + while True: + rows = result.fetchmany(5) + + if rows: + eq_(soft_close.mock_calls, []) + else: + eq_(soft_close.mock_calls, [mock.call()]) + break + elif fetch_style == "fetchall": + rows = result.fetchall() + + eq_(soft_close.mock_calls, [mock.call()]) + else: + assert False + + result.close() + def test_buffered_fetchmany_yield_per_all(self, connection): table = self.tables.test |
