diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-02-11 14:05:49 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-02-11 18:25:52 -0500 |
| commit | 553ac45aae5712e64a5380ba1fa1c6028acf5f39 (patch) | |
| tree | 1a165d582d7bfc1fb78f485f31f8b26d9a35eb10 /test/sql | |
| parent | 89dc4562adb38367ee5fabbcc04ee44968af4906 (diff) | |
| download | sqlalchemy-553ac45aae5712e64a5380ba1fa1c6028acf5f39.tar.gz | |
Apply consistent labeling for all future style ORM queries
Fixed issue in new 1.4/2.0 style ORM queries where a statement-level label
style would not be preserved in the keys used by result rows; this has been
applied to all combinations of Core/ORM columns / session vs. connection
etc. so that the linkage from statement to result row is the same in all
cases.
also repairs a cache key bug where query.from_statement()
vs. select().from_statement() would not be disambiguated; the
compile options were not included in the cache key for
FromStatement.
Fixes: #5933
Change-Id: I22f6cf0f0b3360e55299cdcb2452cead2b2458ea
Diffstat (limited to 'test/sql')
| -rw-r--r-- | test/sql/test_compare.py | 2 | ||||
| -rw-r--r-- | test/sql/test_selectable.py | 39 |
2 files changed, 41 insertions, 0 deletions
diff --git a/test/sql/test_compare.py b/test/sql/test_compare.py index 30235995d..9a4b8b199 100644 --- a/test/sql/test_compare.py +++ b/test/sql/test_compare.py @@ -61,6 +61,7 @@ from sqlalchemy.sql.lambdas import LambdaOptions from sqlalchemy.sql.selectable import _OffsetLimitParam from sqlalchemy.sql.selectable import AliasedReturnsRows from sqlalchemy.sql.selectable import FromGrouping +from sqlalchemy.sql.selectable import LABEL_STYLE_NONE from sqlalchemy.sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL from sqlalchemy.sql.selectable import Select from sqlalchemy.sql.selectable import Selectable @@ -400,6 +401,7 @@ class CoreFixtures(object): select(table_a.c.b, table_a.c.a).set_label_style( LABEL_STYLE_TABLENAME_PLUS_COL ), + select(table_a.c.b, table_a.c.a).set_label_style(LABEL_STYLE_NONE), select(table_a.c.a).where(table_a.c.b == 5), select(table_a.c.a) .where(table_a.c.b == 5) diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py index ce33ed10e..e15c74075 100644 --- a/test/sql/test_selectable.py +++ b/test/sql/test_selectable.py @@ -32,6 +32,7 @@ from sqlalchemy.sql import annotation from sqlalchemy.sql import base from sqlalchemy.sql import column from sqlalchemy.sql import elements +from sqlalchemy.sql import LABEL_STYLE_DISAMBIGUATE_ONLY from sqlalchemy.sql import LABEL_STYLE_TABLENAME_PLUS_COL from sqlalchemy.sql import operators from sqlalchemy.sql import table @@ -2916,6 +2917,7 @@ class ReprTest(fixtures.TestBase): class WithLabelsTest(fixtures.TestBase): def _assert_result_keys(self, s, keys): compiled = s.compile() + eq_(set(compiled._create_result_map()), set(keys)) def _assert_subq_result_keys(self, s, keys): @@ -2934,10 +2936,13 @@ class WithLabelsTest(fixtures.TestBase): self._assert_subq_result_keys(sel, ["x", "x_1"]) + eq_(sel.selected_columns.keys(), ["x", "x"]) + def test_names_overlap_label(self): sel = self._names_overlap().set_label_style( LABEL_STYLE_TABLENAME_PLUS_COL ) + eq_(sel.selected_columns.keys(), ["t1_x", "t2_x"]) eq_(list(sel.selected_columns.keys()), ["t1_x", "t2_x"]) eq_(list(sel.subquery().c.keys()), ["t1_x", "t2_x"]) self._assert_result_keys(sel, ["t1_x", "t2_x"]) @@ -2951,6 +2956,7 @@ class WithLabelsTest(fixtures.TestBase): def test_names_overlap_keys_dont_nolabel(self): sel = self._names_overlap_keys_dont() + eq_(sel.selected_columns.keys(), ["a", "b"]) eq_(list(sel.selected_columns.keys()), ["a", "b"]) eq_(list(sel.subquery().c.keys()), ["a", "b"]) self._assert_result_keys(sel, ["x"]) @@ -2959,10 +2965,41 @@ class WithLabelsTest(fixtures.TestBase): sel = self._names_overlap_keys_dont().set_label_style( LABEL_STYLE_TABLENAME_PLUS_COL ) + eq_(sel.selected_columns.keys(), ["t1_a", "t2_b"]) eq_(list(sel.selected_columns.keys()), ["t1_a", "t2_b"]) eq_(list(sel.subquery().c.keys()), ["t1_a", "t2_b"]) self._assert_result_keys(sel, ["t1_x", "t2_x"]) + def _columns_repeated(self): + m = MetaData() + t1 = Table("t1", m, Column("x", Integer), Column("y", Integer)) + return select(t1.c.x, t1.c.y, t1.c.x).set_label_style(LABEL_STYLE_NONE) + + def test_element_repeated_nolabels(self): + sel = self._columns_repeated().set_label_style(LABEL_STYLE_NONE) + eq_(sel.selected_columns.keys(), ["x", "y", "x"]) + eq_(list(sel.selected_columns.keys()), ["x", "y", "x"]) + eq_(list(sel.subquery().c.keys()), ["x", "y", "x_1"]) + self._assert_result_keys(sel, ["x", "y"]) + + def test_element_repeated_disambiguate(self): + sel = self._columns_repeated().set_label_style( + LABEL_STYLE_DISAMBIGUATE_ONLY + ) + eq_(sel.selected_columns.keys(), ["x", "y", "x_1"]) + eq_(list(sel.selected_columns.keys()), ["x", "y", "x_1"]) + eq_(list(sel.subquery().c.keys()), ["x", "y", "x_1"]) + self._assert_result_keys(sel, ["x", "y", "x__1"]) + + def test_element_repeated_labels(self): + sel = self._columns_repeated().set_label_style( + LABEL_STYLE_TABLENAME_PLUS_COL + ) + eq_(sel.selected_columns.keys(), ["t1_x", "t1_y", "t1_x_1"]) + eq_(list(sel.selected_columns.keys()), ["t1_x", "t1_y", "t1_x_1"]) + eq_(list(sel.subquery().c.keys()), ["t1_x", "t1_y", "t1_x_1"]) + self._assert_result_keys(sel, ["t1_x__1", "t1_x", "t1_y"]) + def _labels_overlap(self): m = MetaData() t1 = Table("t", m, Column("x_id", Integer)) @@ -2971,6 +3008,7 @@ class WithLabelsTest(fixtures.TestBase): def test_labels_overlap_nolabel(self): sel = self._labels_overlap() + eq_(sel.selected_columns.keys(), ["x_id", "id"]) eq_(list(sel.selected_columns.keys()), ["x_id", "id"]) eq_(list(sel.subquery().c.keys()), ["x_id", "id"]) self._assert_result_keys(sel, ["x_id", "id"]) @@ -3077,6 +3115,7 @@ class WithLabelsTest(fixtures.TestBase): def test_keys_overlap_names_dont_nolabel(self): sel = self._keys_overlap_names_dont() + eq_(sel.selected_columns.keys(), ["x", "b_1"]) self._assert_result_keys(sel, ["a", "b"]) def test_keys_overlap_names_dont_label(self): |
