Skip to content

Commit 1ce4e14

Browse files
authored
fix: avoid creating aliases for already-known tables (#361)
Closes #353.
1 parent 392c152 commit 1ce4e14

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

sqlalchemy_bigquery/base.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
from sqlalchemy.engine.default import DefaultDialect, DefaultExecutionContext
5151
from sqlalchemy.engine.base import Engine
5252
from sqlalchemy.sql.schema import Column
53+
from sqlalchemy.sql.schema import Table
5354
from sqlalchemy.sql import elements, selectable
5455
import re
5556

@@ -289,12 +290,18 @@ def visit_column(
289290
if isinstance(tablename, elements._truncated_label):
290291
tablename = self._truncated_identifier("alias", tablename)
291292
elif TABLE_VALUED_ALIAS_ALIASES in kwargs:
292-
aliases = kwargs[TABLE_VALUED_ALIAS_ALIASES]
293-
if tablename not in aliases:
294-
aliases[tablename] = self.anon_map[
295-
f"{TABLE_VALUED_ALIAS_ALIASES} {tablename}"
296-
]
297-
tablename = aliases[tablename]
293+
known_tables = set(
294+
from_.name
295+
for from_ in self.compile_state.froms
296+
if isinstance(from_, Table)
297+
)
298+
if tablename not in known_tables:
299+
aliases = kwargs[TABLE_VALUED_ALIAS_ALIASES]
300+
if tablename not in aliases:
301+
aliases[tablename] = self.anon_map[
302+
f"{TABLE_VALUED_ALIAS_ALIASES} {tablename}"
303+
]
304+
tablename = aliases[tablename]
298305

299306
return self.preparer.quote(tablename) + "." + name
300307

tests/unit/test_compiler.py

+23
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import sqlalchemy.exc
2222

2323
from conftest import setup_table
24+
from conftest import sqlalchemy_1_4_or_higher
2425

2526

2627
def test_constraints_are_ignored(faux_conn, metadata):
@@ -53,3 +54,25 @@ def test_cant_compile_unnamed_column(faux_conn, metadata):
5354
match="Cannot compile Column object until its 'name' is assigned.",
5455
):
5556
sqlalchemy.Column(sqlalchemy.Integer).compile(faux_conn)
57+
58+
59+
@sqlalchemy_1_4_or_higher
60+
def test_no_alias_for_known_tables(faux_conn, metadata):
61+
# See: https://github.com/googleapis/python-bigquery-sqlalchemy/issues/353
62+
table = setup_table(
63+
faux_conn,
64+
"table1",
65+
metadata,
66+
sqlalchemy.Column("foo", sqlalchemy.Integer),
67+
sqlalchemy.Column("bar", sqlalchemy.ARRAY(sqlalchemy.Integer)),
68+
)
69+
F = sqlalchemy.func
70+
q = sqlalchemy.select(table.c.foo).where(F.unnest(table.c.bar).column_valued() == 1)
71+
72+
expected_sql = (
73+
"SELECT `table1`.`foo` \n"
74+
"FROM `table1`, unnest(`table1`.`bar`) AS `anon_1` \n"
75+
"WHERE `anon_1` = %(param_1:INT64)s"
76+
)
77+
found_sql = q.compile(faux_conn).string
78+
assert found_sql == expected_sql

0 commit comments

Comments
 (0)