Skip to content

Commit 862fff9

Browse files
authored
Fix select priority name (#525)
* Fix select map priority name (key) * Fix select map priority name (key) - remove debug code * Fix select map priority name (key) add test
1 parent 0ab526d commit 862fff9

File tree

2 files changed

+85
-11
lines changed

2 files changed

+85
-11
lines changed

aiopg/sa/result.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,7 @@ class ResultMetaData(object):
8989
def __init__(self, result_proxy, metadata):
9090
self._processors = processors = []
9191

92-
result_map = {}
93-
if result_proxy._result_map:
94-
result_map = {elem[0]: elem[3] for elem in
95-
result_proxy._result_map}
92+
map_type, map_column_name = self.result_map(result_proxy._result_map)
9693

9794
# We do not strictly need to store the processor in the key mapping,
9895
# though it is faster in the Python version (probably because of the
@@ -124,11 +121,9 @@ def __init__(self, result_proxy, metadata):
124121
# colname = dialect.normalize_name(colname)
125122

126123
name, obj, type_ = (
127-
colname,
124+
map_column_name.get(colname, colname),
128125
None,
129-
result_map.get(
130-
colname,
131-
typemap.get(coltype, sqltypes.NULLTYPE))
126+
map_type.get(colname, typemap.get(coltype, sqltypes.NULLTYPE))
132127
)
133128

134129
processor = type_._cached_result_processor(dialect, coltype)
@@ -150,7 +145,7 @@ def __init__(self, result_proxy, metadata):
150145
# unambiguous.
151146
primary_keymap[name] = rec = (None, obj, None)
152147

153-
self.keys.append(colname)
148+
self.keys.append(name)
154149
if obj:
155150
for o in obj:
156151
keymap[o] = rec
@@ -163,6 +158,18 @@ def __init__(self, result_proxy, metadata):
163158
# high precedence keymap.
164159
keymap.update(primary_keymap)
165160

161+
def result_map(self, data_map):
162+
data_map = data_map or {}
163+
map_type = {}
164+
map_column_name = {}
165+
for elem in data_map:
166+
name = elem[0]
167+
priority_name = getattr(elem[2][0], 'key', name)
168+
map_type[name] = elem[3] # type column
169+
map_column_name[name] = priority_name
170+
171+
return map_type, map_column_name
172+
166173
def _key_fallback(self, key, raiseerr=True):
167174
map = self._keymap
168175
result = None
@@ -175,9 +182,9 @@ def _key_fallback(self, key, raiseerr=True):
175182
elif isinstance(key, expression.ColumnElement):
176183
if (key._label and key._label in map):
177184
result = map[key._label]
178-
elif (hasattr(key, 'name') and key.name in map):
185+
elif (hasattr(key, 'key') and key.key in map):
179186
# match is only on name.
180-
result = map[key.name]
187+
result = map[key.key]
181188
# search extra hard to make sure this
182189
# isn't a column/label name overlap.
183190
# this check isn't currently available if the row

tests/pep492/test_sa_priority_name.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import pytest
2+
import sqlalchemy as sa
3+
4+
meta = sa.MetaData()
5+
tbl = sa.Table(
6+
'sa_tbl5', meta,
7+
sa.Column('ID', sa.String, primary_key=True, key='id'),
8+
sa.Column('Name', sa.String(255), key='name'),
9+
)
10+
11+
12+
@pytest.fixture
13+
def connect(make_sa_connection, loop):
14+
async def start():
15+
conn = await make_sa_connection()
16+
await conn.execute('DROP TABLE IF EXISTS sa_tbl5')
17+
await conn.execute(
18+
'CREATE TABLE sa_tbl5 ('
19+
'"ID" VARCHAR(255) NOT NULL, '
20+
'"Name" VARCHAR(255), '
21+
'PRIMARY KEY ("ID"))'
22+
)
23+
24+
return conn
25+
26+
return loop.run_until_complete(start())
27+
28+
29+
async def test_priority_name(connect):
30+
await connect.execute(tbl.insert().values(id='test_id', name='test_name'))
31+
row = await (await connect.execute(tbl.select())).fetchone()
32+
assert row.name == 'test_name'
33+
assert row.id == 'test_id'
34+
35+
36+
async def test_priority_name_label(connect):
37+
await connect.execute(tbl.insert().values(id='test_id', name='test_name'))
38+
query = sa.select(
39+
[tbl.c.name.label('test_label_name'), tbl.c.id]
40+
)
41+
query = query.select_from(tbl)
42+
row = await (await connect.execute(query)).fetchone()
43+
assert row.test_label_name == 'test_name'
44+
assert row.id == 'test_id'
45+
46+
47+
async def test_priority_name_and_label(connect):
48+
await connect.execute(tbl.insert().values(id='test_id', name='test_name'))
49+
query = sa.select(
50+
[tbl.c.name.label('test_label_name'), tbl.c.name, tbl.c.id]
51+
)
52+
query = query.select_from(tbl)
53+
row = await (await connect.execute(query)).fetchone()
54+
assert row.test_label_name == 'test_name'
55+
assert row.name == 'test_name'
56+
assert row.id == 'test_id'
57+
58+
59+
async def test_priority_name_all_get(connect):
60+
await connect.execute(tbl.insert().values(id='test_id', name='test_name'))
61+
query = sa.select([tbl.c.name])
62+
query = query.select_from(tbl)
63+
row = await (await connect.execute(query)).fetchone()
64+
assert row.name == 'test_name'
65+
assert row['name'] == 'test_name'
66+
assert row[0] == 'test_name'
67+
assert row[tbl.c.name] == 'test_name'

0 commit comments

Comments
 (0)