Skip to content

Commit 2e4345c

Browse files
committed
fix(sqlalchemy-bigquery): resolve ST function type binding bug and unskip unit tests
1 parent 81390d5 commit 2e4345c

2 files changed

Lines changed: 32 additions & 7 deletions

File tree

packages/sqlalchemy-bigquery/sqlalchemy_bigquery/geography.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,8 @@ def _fixup_st_arguments(element, compiler, **kw):
183183
argument_types = _argument_types.get(element.name.lower())
184184
if argument_types:
185185
for argument_type, argument in zip(argument_types, element.clauses.clauses):
186-
if isinstance(argument, BindParameter) and (
187-
argument.type is not argument_type
188-
or not isinstance(argument.type, argument_type)
186+
if isinstance(argument, BindParameter) and not isinstance(
187+
argument.type, argument_type
189188
):
190189
argument.type = argument_type()
191190

packages/sqlalchemy-bigquery/tests/unit/test_geography.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
geoalchemy2 = pytest.importorskip("geoalchemy2")
2525

2626

27-
# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved.
28-
@pytest.mark.skip(reason="Failing in CI with AssertionError.")
2927
def test_geoalchemy2_core(faux_conn, last_query):
3028
"""Make sure GeoAlchemy 2 Core Tutorial works as adapted to only having geometry"""
3129
conn = faux_conn
@@ -83,7 +81,7 @@ def test_geoalchemy2_core(faux_conn, last_query):
8381
except Exception:
8482
pass # sqlite had no special functions :)
8583
last_query(
86-
"SELECT `lake`.`name`, ST_AsBinary(`lake`.`geog`) AS `geog` \n" "FROM `lake`"
84+
"SELECT `lake`.`name`, ST_AsBinary(`lake`.`geog`) AS `geog` \nFROM `lake`"
8785
)
8886

8987
# Spatial query
@@ -101,7 +99,7 @@ def test_geoalchemy2_core(faux_conn, last_query):
10199
last_query(
102100
"SELECT `lake`.`name` \n"
103101
"FROM `lake` \n"
104-
"WHERE ST_Contains(`lake`.`geog`, %(ST_Contains_1:geography)s)",
102+
"WHERE ST_Contains(`lake`.`geog`, %(ST_Contains_1:STRING)s)",
105103
{"ST_Contains_1": "POINT(4 1)"},
106104
)
107105

@@ -183,3 +181,31 @@ def test_calling_st_functions_that_dont_take_geographies(faux_conn, last_query):
183181
" AS `ST_GeogFromText_1`",
184182
dict(ST_GeogFromText_2="point(0 0)"),
185183
)
184+
185+
186+
def test_fixup_st_arguments():
187+
from geoalchemy2.functions import GenericFunction, ST_Area
188+
from sqlalchemy.sql.elements import BindParameter
189+
190+
from sqlalchemy_bigquery.geography import GEOGRAPHY, _fixup_st_arguments
191+
192+
class DummyCompiler:
193+
def visit_function(self, element, **kw):
194+
return "func(param)"
195+
196+
# Case 1: argument.type is not yet GEOGRAPHY
197+
func_element = ST_Area(BindParameter("param", "point(0 0)"))
198+
res = _fixup_st_arguments(func_element, DummyCompiler())
199+
assert res == "func(param)"
200+
assert isinstance(func_element.clauses.clauses[0].type, GEOGRAPHY)
201+
202+
# Case 2: argument.type is ALREADY GEOGRAPHY
203+
func_element2 = ST_Area(BindParameter("param", "point(0 0)", type_=GEOGRAPHY()))
204+
_fixup_st_arguments(func_element2, DummyCompiler())
205+
206+
# Case 3: function without specified argument types
207+
class ST_Unknown(GenericFunction):
208+
name = "ST_Unknown"
209+
210+
func_element3 = ST_Unknown(BindParameter("param", "point(0 0)"))
211+
_fixup_st_arguments(func_element3, DummyCompiler())

0 commit comments

Comments
 (0)