diff options
| author | J. Nick Koston <nick@koston.org> | 2023-04-19 18:39:18 -0400 |
|---|---|---|
| committer | Federico Caselli <cfederico87@gmail.com> | 2023-04-26 20:19:17 +0200 |
| commit | ff198e35f0e04b8d38df25df234e72259069b4d1 (patch) | |
| tree | c48db9a0366b48c8caaa35ad9ab83a354aaa7d32 /test/sql | |
| parent | 9f675fd042b05977f1b38887c2fbbb54ecd424f7 (diff) | |
| download | sqlalchemy-ff198e35f0e04b8d38df25df234e72259069b4d1.tar.gz | |
Prebuild the row string to position lookup for Rows
Improved :class:`_engine.Row` implementation to optimize
``__getattr__`` performance.
The serialization of a :class:`_engine.Row` to pickle has changed with
this change. Pickle saved by older SQLAlchemy versions can still be loaded,
but new pickle saved by this version cannot be loaded by older ones.
Fixes: #9678
Closes: #9668
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9668
Pull-request-sha: 86b8ccd1959dbd91b1208f7a648a91f217e1f866
Change-Id: Ia85c26a59e1a57ba2bf0d65578c6168f82a559f2
Diffstat (limited to 'test/sql')
| -rw-r--r-- | test/sql/test_resultset.py | 82 |
1 files changed, 23 insertions, 59 deletions
diff --git a/test/sql/test_resultset.py b/test/sql/test_resultset.py index e382a7fb6..bf5e30e3c 100644 --- a/test/sql/test_resultset.py +++ b/test/sql/test_resultset.py @@ -38,7 +38,6 @@ from sqlalchemy.engine import cursor as _cursor from sqlalchemy.engine import default from sqlalchemy.engine import Row from sqlalchemy.engine.result import SimpleResultMetaData -from sqlalchemy.engine.row import KEY_INTEGER_ONLY from sqlalchemy.ext.compiler import compiles from sqlalchemy.sql import ColumnElement from sqlalchemy.sql import expression @@ -201,7 +200,6 @@ class CursorResultTest(fixtures.TablesTest): rows[0].user_id 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") @@ -378,7 +376,6 @@ class CursorResultTest(fixtures.TablesTest): operator.ge, operator.le, ]: - try: control = op(equal, compare) except TypeError: @@ -994,18 +991,14 @@ class CursorResultTest(fixtures.TablesTest): def test_column_accessor_err(self, connection): r = connection.execute(select(1)).first() - assert_raises_message( - AttributeError, - "Could not locate column in row for column 'foo'", - getattr, - r, - "foo", - ) - assert_raises_message( - KeyError, - "Could not locate column in row for column 'foo'", - lambda: r._mapping["foo"], - ) + with expect_raises_message( + AttributeError, "Could not locate column in row for column 'foo'" + ): + r.foo + with expect_raises_message( + KeyError, "Could not locate column in row for column 'foo'" + ): + r._mapping["foo"], def test_graceful_fetch_on_non_rows(self): """test that calling fetchone() etc. on a result that doesn't @@ -1069,9 +1062,9 @@ class CursorResultTest(fixtures.TablesTest): eq_(list(row._fields), ["case_insensitive", "CaseSensitive"]) - in_("case_insensitive", row._keymap) - in_("CaseSensitive", row._keymap) - not_in("casesensitive", row._keymap) + in_("case_insensitive", row._parent._keymap) + in_("CaseSensitive", row._parent._keymap) + not_in("casesensitive", row._parent._keymap) eq_(row._mapping["case_insensitive"], 1) eq_(row._mapping["CaseSensitive"], 2) @@ -1094,9 +1087,9 @@ class CursorResultTest(fixtures.TablesTest): ["case_insensitive", "CaseSensitive", "screw_up_the_cols"], ) - in_("case_insensitive", row._keymap) - in_("CaseSensitive", row._keymap) - not_in("casesensitive", row._keymap) + in_("case_insensitive", row._parent._keymap) + in_("CaseSensitive", row._parent._keymap) + not_in("casesensitive", row._parent._keymap) eq_(row._mapping["case_insensitive"], 1) eq_(row._mapping["CaseSensitive"], 2) @@ -1718,15 +1711,11 @@ class CursorResultTest(fixtures.TablesTest): def __getitem__(self, i): return list.__getitem__(self.internal_list, i) - proxy = Row( - object(), - [None], - {"key": (0, None, "key"), 0: (0, None, "key")}, - Row._default_key_style, - MyList(["value"]), - ) + parent = SimpleResultMetaData(["key"]) + proxy = Row(parent, [None], parent._key_to_index, MyList(["value"])) eq_(list(proxy), ["value"]) eq_(proxy[0], "value") + eq_(proxy.key, "value") eq_(proxy._mapping["key"], "value") def test_no_rowcount_on_selects_inserts(self, metadata, testing_engine): @@ -1769,14 +1758,7 @@ class CursorResultTest(fixtures.TablesTest): eq_(len(mock_rowcount.__get__.mock_calls), 2) def test_row_is_sequence(self): - - row = Row( - object(), - [None], - {"key": (None, 0), 0: (None, 0)}, - Row._default_key_style, - ["value"], - ) + row = Row(object(), [None], {}, ["value"]) is_true(isinstance(row, collections_abc.Sequence)) def test_row_special_names(self): @@ -1784,8 +1766,7 @@ class CursorResultTest(fixtures.TablesTest): row = Row( metadata, [None, None, None, None], - metadata._keymap, - Row._default_key_style, + metadata._key_to_index, ["kv", "cv", "iv", "f"], ) is_true(isinstance(row, collections_abc.Sequence)) @@ -1803,8 +1784,7 @@ class CursorResultTest(fixtures.TablesTest): row = Row( metadata, [None, None, None], - metadata._keymap, - Row._default_key_style, + metadata._key_to_index, ["kv", "cv", "iv"], ) is_true(isinstance(row, collections_abc.Sequence)) @@ -1818,18 +1798,11 @@ class CursorResultTest(fixtures.TablesTest): def test_new_row_no_dict_behaviors(self): """This mode is not used currently but will be once we are in 2.0.""" - metadata = SimpleResultMetaData( - [ - "a", - "b", - "count", - ] - ) + metadata = SimpleResultMetaData(["a", "b", "count"]) row = Row( metadata, [None, None, None], - metadata._keymap, - KEY_INTEGER_ONLY, + metadata._key_to_index, ["av", "bv", "cv"], ) @@ -1850,14 +1823,7 @@ class CursorResultTest(fixtures.TablesTest): eq_(list(row._mapping), ["a", "b", "count"]) def test_row_is_hashable(self): - - row = Row( - object(), - [None, None, None], - {"key": (None, 0), 0: (None, 0)}, - Row._default_key_style, - (1, "value", "foo"), - ) + row = Row(object(), [None, None, None], {}, (1, "value", "foo")) eq_(hash(row), hash((1, "value", "foo"))) @testing.provide_metadata @@ -3459,7 +3425,6 @@ class AlternateCursorResultTest(fixtures.TablesTest): r = conn.execute(select(self.table)) assert isinstance(r.cursor_strategy, strategy_cls) with mock.patch.object(r, "cursor", cursor()): - with testing.expect_raises_message( IOError, "random non-DBAPI" ): @@ -3523,7 +3488,6 @@ class MergeCursorResultTest(fixtures.TablesTest): users = self.tables.users def results(connection): - r1 = connection.execute( users.select() .where(users.c.user_id.in_([7, 8])) |
