summaryrefslogtreecommitdiff
path: root/test/sql
diff options
context:
space:
mode:
authorJ. Nick Koston <nick@koston.org>2023-04-19 18:39:18 -0400
committerFederico Caselli <cfederico87@gmail.com>2023-04-26 20:19:17 +0200
commitff198e35f0e04b8d38df25df234e72259069b4d1 (patch)
treec48db9a0366b48c8caaa35ad9ab83a354aaa7d32 /test/sql
parent9f675fd042b05977f1b38887c2fbbb54ecd424f7 (diff)
downloadsqlalchemy-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.py82
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]))