Skip to content

Commit ad5baf8

Browse files
author
Jim Fulton
authored
fix: distinct doesn't work as a column wrapper (#275)
1 parent e06bf74 commit ad5baf8

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

sqlalchemy_bigquery/base.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,12 @@ def visit_insert(self, insert_stmt, asfrom=False, **kw):
247247
)
248248

249249
def visit_column(
250-
self, column, add_to_result_map=None, include_table=True, **kwargs
250+
self,
251+
column,
252+
add_to_result_map=None,
253+
include_table=True,
254+
result_map_targets=(),
255+
**kwargs,
251256
):
252257
name = orig_name = column.name
253258
if name is None:
@@ -258,7 +263,12 @@ def visit_column(
258263
name = self._truncated_identifier("colident", name)
259264

260265
if add_to_result_map is not None:
261-
add_to_result_map(name, orig_name, (column, name, column.key), column.type)
266+
targets = (column, name, column.key) + result_map_targets
267+
if getattr(column, "_tq_label", None):
268+
# _tq_label was added in SQLAlchemy 1.4
269+
targets += (column._tq_label,)
270+
271+
add_to_result_map(name, orig_name, targets, column.type)
262272

263273
if is_literal:
264274
name = self.escape_literal_column(name)
@@ -271,6 +281,7 @@ def visit_column(
271281
tablename = table.name
272282
if isinstance(tablename, elements._truncated_label):
273283
tablename = self._truncated_identifier("alias", tablename)
284+
274285
return self.preparer.quote(tablename) + "." + name
275286

276287
def visit_label(self, *args, within_group_by=False, **kwargs):

tests/system/conftest.py

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from typing import List
2222

2323
import pytest
24+
import sqlalchemy
2425

2526
from google.cloud import bigquery
2627
import test_utils.prefixer
@@ -137,3 +138,8 @@ def cleanup_datasets(bigquery_client: bigquery.Client):
137138
bigquery_client.delete_dataset(
138139
dataset, delete_contents=True, not_found_ok=True
139140
)
141+
142+
143+
@pytest.fixture
144+
def metadata():
145+
return sqlalchemy.MetaData()

tests/system/test_sqlalchemy_bigquery.py

+34
Original file line numberDiff line numberDiff line change
@@ -691,3 +691,37 @@ def test_has_table(engine, engine_using_test_dataset, bigquery_dataset):
691691
assert engine_using_test_dataset.has_table(f"{bigquery_dataset}.sample") is True
692692

693693
assert engine_using_test_dataset.has_table("sample_alt") is False
694+
695+
696+
def test_distinct_188(engine, bigquery_dataset):
697+
from sqlalchemy.ext.declarative import declarative_base
698+
from sqlalchemy import Column, Integer
699+
from sqlalchemy.orm import sessionmaker
700+
701+
Base = declarative_base()
702+
703+
class MyTable(Base):
704+
__tablename__ = f"{bigquery_dataset}.test_distinct_188"
705+
id = Column(Integer, primary_key=True)
706+
my_column = Column(Integer)
707+
708+
MyTable.__table__.create(engine)
709+
710+
Session = sessionmaker(bind=engine)
711+
db = Session()
712+
db.add_all([MyTable(id=i, my_column=i % 2) for i in range(9)])
713+
db.commit()
714+
715+
expected = [(0,), (1,)]
716+
717+
assert sorted(db.query(MyTable.my_column).distinct().all()) == expected
718+
assert (
719+
sorted(
720+
db.query(
721+
sqlalchemy.distinct(MyTable.my_column).label("just_a_random_label")
722+
).all()
723+
)
724+
== expected
725+
)
726+
727+
assert sorted(db.query(sqlalchemy.distinct(MyTable.my_column)).all()) == expected

0 commit comments

Comments
 (0)