Skip to content

Commit f05c58e

Browse files
committed
fix(sqlalchemy-bigquery): wrap GEOGRAPHY bind arguments with ST_GeogFromText in _fixup_st_arguments
1 parent 8bd2644 commit f05c58e

23 files changed

Lines changed: 67 additions & 57 deletions

packages/sqlalchemy-bigquery/sqlalchemy_bigquery/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
SQLAlchemy dialect for Google BigQuery
2121
"""
2222

23+
import sys
2324
import warnings
2425

2526
from ._types import (
@@ -43,7 +44,6 @@
4344
)
4445
from .base import BigQueryDialect, dialect
4546
from .version import __version__
46-
import sys
4747

4848
# Now that support for Python 3.7, 3.8 and 3.9 has been removed, we don't expect the
4949
# following check to succeed. The warning is only included for robustness.

packages/sqlalchemy-bigquery/sqlalchemy_bigquery/_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
import re
1111
from typing import Optional
1212

13-
from google.api_core import client_info
1413
import google.auth
14+
import sqlalchemy
15+
from google.api_core import client_info
1516
from google.cloud import bigquery
1617
from google.oauth2 import service_account
17-
import sqlalchemy
1818

1919
USER_AGENT_TEMPLATE = "sqlalchemy/{}"
2020
SCOPES = (

packages/sqlalchemy-bigquery/sqlalchemy_bigquery/_struct.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1818
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1919

20-
from sqlalchemy.sql import operators
2120
import sqlalchemy.sql.coercions
2221
import sqlalchemy.sql.default_comparator
2322
import sqlalchemy.sql.roles
2423
import sqlalchemy.sql.sqltypes
2524
import sqlalchemy.types
25+
from sqlalchemy.sql import operators
2626

2727
# from . import base # Moved to _get_subtype_col_spec to break circular import
2828

packages/sqlalchemy-bigquery/sqlalchemy_bigquery/_types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1818
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1919

20-
from google.cloud.bigquery.schema import SchemaField
2120
import sqlalchemy.types
2221
import sqlalchemy.util
22+
from google.cloud.bigquery.schema import SchemaField
2323

2424
try:
2525
from .geography import GEOGRAPHY

packages/sqlalchemy-bigquery/sqlalchemy_bigquery/base.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,28 @@
2020
"""Integration between SQLAlchemy and BigQuery."""
2121

2222
import datetime
23-
from decimal import Decimal
2423
import operator
2524
import random
2625
import re
2726
import uuid
27+
from decimal import Decimal
2828

29-
from google import auth
3029
import google.api_core.exceptions
30+
import packaging.version
31+
import sqlalchemy
32+
import sqlalchemy.sql.expression
33+
import sqlalchemy.sql.functions
34+
import sqlalchemy.sql.sqltypes
35+
import sqlalchemy.sql.type_api
36+
import sqlalchemy_bigquery_vendored.sqlalchemy.postgresql.base as vendored_postgresql
37+
from google import auth
3138
from google.api_core.exceptions import NotFound
3239
from google.cloud.bigquery import ConnectionProperty, QueryJobConfig, dbapi
3340
from google.cloud.bigquery.table import (
3441
RangePartitioning,
3542
TableReference,
3643
TimePartitioning,
3744
)
38-
import packaging.version
39-
import sqlalchemy
4045
from sqlalchemy import util
4146
from sqlalchemy.engine.base import Engine
4247
from sqlalchemy.engine.default import DefaultDialect, DefaultExecutionContext
@@ -49,14 +54,9 @@
4954
IdentifierPreparer,
5055
SQLCompiler,
5156
)
52-
import sqlalchemy.sql.expression
53-
import sqlalchemy.sql.functions
5457
from sqlalchemy.sql.schema import Column, Table
5558
from sqlalchemy.sql.selectable import CTE
56-
import sqlalchemy.sql.sqltypes
5759
from sqlalchemy.sql.sqltypes import Integer, NullType, Numeric, String
58-
import sqlalchemy.sql.type_api
59-
import sqlalchemy_bigquery_vendored.sqlalchemy.postgresql.base as vendored_postgresql
6060

6161
from . import _helpers, _types
6262
from .parse_url import parse_url

packages/sqlalchemy-bigquery/sqlalchemy_bigquery/geography.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919

2020
import geoalchemy2
2121
import geoalchemy2.functions
22+
import sqlalchemy.ext.compiler
2223
from geoalchemy2.shape import to_shape
2324
from shapely import wkb, wkt
24-
import sqlalchemy.ext.compiler
2525
from sqlalchemy.sql.elements import BindParameter
2626

2727
SRID = 4326 # WGS84, https://spatialreference.org/ref/epsg/wgs-84/
@@ -182,11 +182,19 @@ def _fixup_st_arguments(element, compiler, **kw):
182182
"""
183183
argument_types = _argument_types.get(element.name.lower())
184184
if argument_types:
185+
new_clauses = []
186+
modified = False
185187
for argument_type, argument in zip(argument_types, element.clauses.clauses):
186188
if isinstance(argument, BindParameter) and not isinstance(
187189
argument.type, argument_type
188190
):
189191
argument.type = argument_type()
192+
if issubclass(argument_type, GEOGRAPHY):
193+
argument = geoalchemy2.functions.ST_GeogFromText(argument)
194+
modified = True
195+
new_clauses.append(argument)
196+
if modified:
197+
element.clauses.clauses = new_clauses
190198

191199
return compiler.visit_function(element, **kw)
192200

packages/sqlalchemy-bigquery/tests/sqlalchemy_dialect_compliance/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import traceback
2323

2424
import google.cloud.bigquery.dbapi.connection
25+
import test_utils.prefixer
2526
from sqlalchemy.testing import config
2627
from sqlalchemy.testing.plugin.pytestplugin import * # noqa
2728
from sqlalchemy.testing.plugin.pytestplugin import (
@@ -30,7 +31,6 @@
3031
from sqlalchemy.testing.plugin.pytestplugin import (
3132
pytest_sessionstart as _pytest_sessionstart,
3233
)
33-
import test_utils.prefixer
3434

3535
import sqlalchemy_bigquery.base
3636

packages/sqlalchemy-bigquery/tests/sqlalchemy_dialect_compliance/test_dialect_compliance.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,34 @@
2525
import pytest
2626
import pytz
2727
import sqlalchemy
28-
from sqlalchemy import and_
2928
import sqlalchemy.sql.sqltypes
29+
import sqlalchemy.testing.suite.test_types
30+
from sqlalchemy import and_
3031
from sqlalchemy.testing import config, util
3132
from sqlalchemy.testing.assertions import eq_
33+
from sqlalchemy.testing.suite import * # noqa
3234
from sqlalchemy.testing.suite import (
35+
Column,
36+
DistinctOnTest,
37+
HasIndexTest,
38+
IdentityAutoincrementTest,
3339
Integer,
3440
LongNameBlowoutTest,
3541
PostCompileParamsTest,
3642
QuotedNameArgumentTest,
37-
)
38-
from sqlalchemy.testing.suite import (
43+
String,
44+
Table,
3945
WindowFunctionTest,
4046
bindparam,
4147
exists,
4248
select,
4349
testing,
4450
)
45-
from sqlalchemy.testing.suite import * # noqa
4651
from sqlalchemy.testing.suite import CTETest as _CTETest
47-
from sqlalchemy.testing.suite import Column
48-
from sqlalchemy.testing.suite import DistinctOnTest
49-
from sqlalchemy.testing.suite import ExistsTest as _ExistsTest
50-
from sqlalchemy.testing.suite import HasIndexTest, IdentityAutoincrementTest
51-
from sqlalchemy.testing.suite import InsertBehaviorTest as _InsertBehaviorTest
52-
from sqlalchemy.testing.suite import String, Table
5352
from sqlalchemy.testing.suite import DifficultParametersTest as _DifficultParametersTest
53+
from sqlalchemy.testing.suite import ExistsTest as _ExistsTest
5454
from sqlalchemy.testing.suite import FetchLimitOffsetTest as _FetchLimitOffsetTest
55+
from sqlalchemy.testing.suite import InsertBehaviorTest as _InsertBehaviorTest
5556
from sqlalchemy.testing.suite import SimpleUpdateDeleteTest as _SimpleUpdateDeleteTest
5657
from sqlalchemy.testing.suite import (
5758
TimestampMicrosecondsTest as _TimestampMicrosecondsTest,
@@ -62,7 +63,6 @@
6263
ComponentReflectionTestExtra,
6364
HasTableTest,
6465
)
65-
import sqlalchemy.testing.suite.test_types
6666
from sqlalchemy.testing.suite.test_types import ArrayTest
6767

6868
if packaging.version.parse(sqlalchemy.__version__) >= packaging.version.parse("2.0"):
@@ -637,8 +637,12 @@ def test_no_results_for_non_returning_insert(cls):
637637
del DistinctOnTest # expects unquoted table names.
638638
del HasIndexTest # BQ doesn't do the indexes that SQLA is loooking for.
639639
del IdentityAutoincrementTest # BQ doesn't do autoincrement
640-
del LongNameBlowoutTest # Requires features (indexes, primary keys, etc., that BigQuery doesn't have.
641-
del PostCompileParamsTest # BQ adds backticks to bind parameters, causing failure of tests TODO: fix this?
640+
del (
641+
LongNameBlowoutTest
642+
) # Requires features (indexes, primary keys, etc., that BigQuery doesn't have.
643+
del (
644+
PostCompileParamsTest
645+
) # BQ adds backticks to bind parameters, causing failure of tests TODO: fix this?
642646
del QuotedNameArgumentTest # Quotes aren't allowed in BigQuery table names.
643647
del (
644648
WindowFunctionTest.test_window_rows_between

packages/sqlalchemy-bigquery/tests/system/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
import pathlib
2121
from typing import List
2222

23-
from google.api_core import exceptions
24-
from google.cloud import bigquery
2523
import pytest
2624
import sqlalchemy
2725
import test_utils.prefixer
2826
import test_utils.retry
27+
from google.api_core import exceptions
28+
from google.cloud import bigquery
2929

3030
from sqlalchemy_bigquery import BigQueryDialect
3131

packages/sqlalchemy-bigquery/tests/system/test_alembic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import contextlib
2121

2222
import google.api_core.exceptions
23-
from google.cloud.bigquery import SchemaField, TimePartitioning
2423
import pytest
24+
from google.cloud.bigquery import SchemaField, TimePartitioning
2525
from sqlalchemy import Column, DateTime, Integer, Numeric, String
2626

2727
alembic = pytest.importorskip("alembic")

0 commit comments

Comments
 (0)