Skip to content

Commit b312b5c

Browse files
committed
Address SQLAlchemy and Datastore warning coverage
Update the dialect for newer SQLAlchemy and Google Datastore client behavior without hiding warnings globally. Add import_dbapi while keeping dbapi as a compatibility wrapper, and set supports_statement_cache to False so SQLAlchemy does not warn about an unsupported statement cache contract. Use google.cloud.datastore.query.PropertyFilter in get_columns to avoid the Datastore positional add_filter deprecation path. Adjust integration tests that only need to locate inserted emulator entities so they no longer call the deprecated add_filter form. Improve the unknown BigQuery type unit test to assert the expected SQLAlchemy SAWarning and NullType fallback. UNKNOWN_TYPE_XYZ is intentionally unsupported in the test fixture, so the warning is part of the expected behavior rather than something to suppress. Do not raise requires-python to 3.11 in this commit. The current google-cloud-datastore 2.26.0 metadata still supports Python >=3.10; moving this project to Python >=3.11 should be handled as a separate support-policy change because Python 3.10 remains inside the declared project range even though Google now warns about its 2026-10-04 EOL.
1 parent 3ec0c7a commit b312b5c

3 files changed

Lines changed: 29 additions & 9 deletions

File tree

‎sqlalchemy_datastore/base.py‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from typing import Any, List, Optional
2121

2222
from google.cloud import firestore_admin_v1
23+
from google.cloud.datastore.query import PropertyFilter
2324
from google.oauth2 import service_account
2425
from sqlalchemy import exc
2526
from sqlalchemy.engine import Connection, default
@@ -54,6 +55,7 @@ class CloudDatastoreDialect(default.DefaultDialect):
5455
supports_unicode_binds = True
5556
returns_unicode_strings = True
5657
description_encoding = None
58+
supports_statement_cache = False
5759

5860
# JSON support - required for SQLAlchemy JSON type
5961
_json_serializer = None
@@ -88,10 +90,15 @@ def __init__(
8890
self._client = None
8991

9092
@classmethod
91-
def dbapi(cls):
93+
def import_dbapi(cls):
9294
"""Return the DBAPI 2.0 driver."""
9395
return datastore_dbapi
9496

97+
@classmethod
98+
def dbapi(cls):
99+
"""Return the DBAPI 2.0 driver."""
100+
return cls.import_dbapi()
101+
95102
def do_ping(self, dbapi_connection):
96103
"""Performs a simple operation to check if the connection is still alive."""
97104
try:
@@ -212,7 +219,7 @@ def get_columns(
212219
"""Retrieve column information from the database."""
213220
client = self._client
214221
query = client.query(kind="__Stat_PropertyType_PropertyName_Kind__")
215-
query.add_filter("kind_name", "=", table_name)
222+
query.add_filter(filter=PropertyFilter("kind_name", "=", table_name))
216223
properties = list(query.fetch())
217224

218225
return [

‎tests/test_integration_queries.py‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ def test_update_user(conn, datastore_client):
3333

3434
# Find the inserted entity by querying the datastore client directly
3535
query = datastore_client.query(kind="users")
36-
query.add_filter("name", "=", "UpdateTestUser")
37-
entities = list(query.fetch())
36+
entities = [
37+
entity for entity in query.fetch()
38+
if entity.get("name") == "UpdateTestUser"
39+
]
3840
assert len(entities) >= 1
3941
entity_id = entities[0].key.id
4042

@@ -62,8 +64,10 @@ def test_delete_user(conn, datastore_client):
6264

6365
# Find the inserted entity
6466
query = datastore_client.query(kind="users")
65-
query.add_filter("name", "=", "DeleteTestUser")
66-
entities = list(query.fetch())
67+
entities = [
68+
entity for entity in query.fetch()
69+
if entity.get("name") == "DeleteTestUser"
70+
]
6771
assert len(entities) >= 1
6872
entity_id = entities[0].key.id
6973

@@ -332,8 +336,10 @@ def test_task_insert_update_delete_raw_sql(conn, datastore_client):
332336

333337
# Find the inserted entity
334338
query = datastore_client.query(kind="tasks")
335-
query.add_filter("task", "=", "Coverage Test Task")
336-
entities = list(query.fetch())
339+
entities = [
340+
entity for entity in query.fetch()
341+
if entity.get("task") == "Coverage Test Task"
342+
]
337343
assert len(entities) >= 1
338344
entity_id = entities[0].key.id
339345

‎tests/test_unit_types.py‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
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
"""Unit tests for _types module (no emulator required)."""
20+
import pytest
2021
import sqlalchemy.types
2122
from google.cloud.bigquery.schema import SchemaField
2223

@@ -190,7 +191,13 @@ def test_get_sqla_column_type_repeated():
190191

191192
def test_get_sqla_column_type_unknown():
192193
field = SchemaField("mystery", "UNKNOWN_TYPE_XYZ")
193-
coltype = _get_sqla_column_type(field)
194+
195+
with pytest.warns(
196+
sqlalchemy.exc.SAWarning,
197+
match="Did not recognize type 'UNKNOWN_TYPE_XYZ' of column 'mystery'",
198+
):
199+
coltype = _get_sqla_column_type(field)
200+
194201
assert coltype is sqlalchemy.types.NullType
195202

196203

0 commit comments

Comments
 (0)