diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-05-04 13:31:51 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-05-04 13:49:43 -0400 |
| commit | d6ec248fa7083fee93b669ab27474f6c8f69944d (patch) | |
| tree | 6f244ef0bde129a4519ca4439e25d8150a58b2b3 /test/sql | |
| parent | f1f4f466fd809a14bff6d0c405a1d5da87438379 (diff) | |
| download | sqlalchemy-d6ec248fa7083fee93b669ab27474f6c8f69944d.tar.gz | |
Establish deprecation path for CursorResult.keys()
Established a deprecation path for calling upon the
:meth:`_cursor.CursorResult.keys` method for a statement that returns no
rows to provide support for legacy patterns used by the "records" package
as well as any other non-migrated applications. Previously, this would
raise :class:`.ResourceClosedException` unconditionally in the same way as
it does when attempting to fetch rows. While this is the correct behavior
going forward, the :class:`_cursor.LegacyCursorResult` object will now in
this case return an empty list for ``.keys()`` as it did in 1.3, while also
emitting a 2.0 deprecation warning. The :class:`_cursor.CursorResult`, used
when using a 2.0-style "future" engine, will continue to raise as it does
now.
Fixes: #6427
Change-Id: I4148f28c88039e4141deeab28b1a5994e6d6e098
Diffstat (limited to 'test/sql')
| -rw-r--r-- | test/sql/test_deprecations.py | 26 | ||||
| -rw-r--r-- | test/sql/test_resultset.py | 35 |
2 files changed, 47 insertions, 14 deletions
diff --git a/test/sql/test_deprecations.py b/test/sql/test_deprecations.py index 4af1f65e3..db2042f5b 100644 --- a/test/sql/test_deprecations.py +++ b/test/sql/test_deprecations.py @@ -1467,11 +1467,11 @@ class ConnectionlessCursorResultTest(fixtures.TablesTest): "This result object does not return rows.", result.fetchone, ) - assert_raises_message( - exc.ResourceClosedError, - "This result object does not return rows.", - result.keys, - ) + + with testing.expect_deprecated_20( + r"Calling the .keys\(\) method on a result set that does not " + ): + eq_(result.keys(), []) class CursorResultTest(fixtures.TablesTest): @@ -1554,6 +1554,22 @@ class CursorResultTest(fixtures.TablesTest): ): eq_(r._mapping[users.c.user_name], "jack") + def test_keys_no_rows(self, connection): + + for i in range(2): + r = connection.execute( + text("update users set user_name='new' where user_id=10") + ) + + with testing.expect_deprecated( + r"Calling the .keys\(\) method on a result set that does not " + r"return rows is deprecated and will raise " + r"ResourceClosedError in SQLAlchemy 2.0." + ): + list_ = r.keys() + eq_(list_, []) + list_.append("Don't cache me") + def test_column_accessor_basic_text(self, connection): users = self.tables.users diff --git a/test/sql/test_resultset.py b/test/sql/test_resultset.py index c0c16512c..2054b3cf1 100644 --- a/test/sql/test_resultset.py +++ b/test/sql/test_resultset.py @@ -627,7 +627,12 @@ class CursorResultTest(fixtures.TablesTest): lambda: r._mapping["foo"], ) - def test_graceful_fetch_on_non_rows(self): + @testing.combinations( + (True,), + (False,), + argnames="future", + ) + def test_graceful_fetch_on_non_rows(self, future): """test that calling fetchone() etc. on a result that doesn't return rows fails gracefully. @@ -642,6 +647,10 @@ class CursorResultTest(fixtures.TablesTest): users = self.tables.users conn = testing.db.connect() + if future: + conn = conn.execution_options(future_result=True) + keys_lambda = lambda r: r.keys() # noqa: E731 + for meth in [ lambda r: r.fetchone(), lambda r: r.fetchall(), @@ -649,19 +658,27 @@ class CursorResultTest(fixtures.TablesTest): lambda r: r.scalar(), lambda r: r.fetchmany(), lambda r: r._getter("user"), - lambda r: r.keys(), + keys_lambda, lambda r: r.columns("user"), lambda r: r.cursor_strategy.fetchone(r, r.cursor), ]: trans = conn.begin() result = conn.execute(users.insert(), dict(user_id=1)) - assert_raises_message( - exc.ResourceClosedError, - "This result object does not return rows. " - "It has been closed automatically.", - meth, - result, - ) + + if not future and meth is keys_lambda: + with testing.expect_deprecated( + r"Calling the .keys\(\) method on a result set that does " + r"not return rows is deprecated" + ): + eq_(meth(result), []) + else: + assert_raises_message( + exc.ResourceClosedError, + "This result object does not return rows. " + "It has been closed automatically.", + meth, + result, + ) trans.rollback() def test_fetchone_til_end(self, connection): |
