Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.

Commit 3448a12

Browse files
committed
fix(spanner): ensure session pool is bound before database use
1 parent 1d2f042 commit 3448a12

File tree

11 files changed

+221
-191
lines changed

11 files changed

+221
-191
lines changed

google/cloud/spanner_v1/_async/database.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
"""User-friendly container for Cloud Spanner Database."""
1616
__CROSS_SYNC_OUTPUT__ = "google.cloud.spanner_v1.database"
17-
import asyncio
1817
import copy
1918
import functools
20-
import inspect
2119
import logging
2220
import re
2321
import threading
@@ -223,14 +221,8 @@ def __init__(
223221
pool = BurstyPool(database_role=database_role)
224222

225223
self._pool = pool
226-
res = pool.bind(self)
227-
try:
228-
loop = asyncio.get_running_loop()
229-
if loop.is_running() and inspect.isawaitable(res):
230-
loop.create_task(res)
231-
except RuntimeError:
232-
# No running loop, bind should have been sync or will be failed later
233-
pass
224+
# Note: self._pool.bind(self) should be called via Instance.database()
225+
# factory method to ensure proper async initialization.
234226
self._experimental_host = (
235227
self._instance.experimental_host if self._instance else None
236228
)

google/cloud/spanner_v1/_async/instance.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,8 @@ async def delete(self):
433433

434434
await api.delete_instance(name=self.name, metadata=metadata)
435435

436-
def database(
436+
@CrossSync.convert
437+
async def database(
437438
self,
438439
database_id,
439440
ddl_statements=(),
@@ -498,7 +499,7 @@ def database(
498499
"""
499500

500501
if not enable_interceptors_in_tests:
501-
return Database(
502+
db = Database(
502503
database_id,
503504
self,
504505
ddl_statements=ddl_statements,
@@ -511,7 +512,7 @@ def database(
511512
proto_descriptors=proto_descriptors,
512513
)
513514
else:
514-
return TestDatabase(
515+
db = TestDatabase(
515516
database_id,
516517
self,
517518
ddl_statements=ddl_statements,
@@ -523,6 +524,9 @@ def database(
523524
enable_drop_protection=enable_drop_protection,
524525
)
525526

527+
await db._pool.bind(db)
528+
return db
529+
526530
@CrossSync.convert
527531
async def list_databases(self, page_size=None):
528532
"""List databases for the instance.

google/cloud/spanner_v1/database.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@
1616
# This file is automatically generated by CrossSync. Do not edit manually.
1717

1818
"""User-friendly container for Cloud Spanner Database."""
19-
import asyncio
2019
import copy
2120
import functools
22-
import inspect
2321
import logging
2422
import re
2523
import threading
@@ -203,13 +201,6 @@ def __init__(
203201
if pool is None:
204202
pool = BurstyPool(database_role=database_role)
205203
self._pool = pool
206-
res = pool.bind(self)
207-
try:
208-
loop = asyncio.get_running_loop()
209-
if loop.is_running() and inspect.isawaitable(res):
210-
loop.create_task(res)
211-
except RuntimeError:
212-
pass
213204
self._experimental_host = (
214205
self._instance.experimental_host if self._instance else None
215206
)

google/cloud/spanner_v1/instance.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ def database(
455455
:rtype: :class:`~google.cloud.spanner_v1.database.Database`
456456
:returns: a database owned by this instance."""
457457
if not enable_interceptors_in_tests:
458-
return Database(
458+
db = Database(
459459
database_id,
460460
self,
461461
ddl_statements=ddl_statements,
@@ -468,7 +468,7 @@ def database(
468468
proto_descriptors=proto_descriptors,
469469
)
470470
else:
471-
return TestDatabase(
471+
db = TestDatabase(
472472
database_id,
473473
self,
474474
ddl_statements=ddl_statements,
@@ -479,6 +479,8 @@ def database(
479479
database_role=database_role,
480480
enable_drop_protection=enable_drop_protection,
481481
)
482+
db._pool.bind(db)
483+
return db
482484

483485
def list_databases(self, page_size=None):
484486
"""List databases for the instance.

tests/_builders.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ def build_database(**kwargs: Mapping) -> Database:
174174
database = cls(**kwargs)
175175
database._spanner_api = build_spanner_api()
176176

177+
if not is_async:
178+
database._pool.bind(database)
179+
177180
return database
178181

179182

tests/system/_async/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ async def shared_database(
145145
pool = spanner_v1.AsyncBurstyPool(labels={"testcase": "database_api_async"})
146146

147147
if database_dialect == DatabaseDialect.POSTGRESQL:
148-
database = shared_instance.database(
148+
database = await shared_instance.database(
149149
database_name,
150150
pool=pool,
151151
database_dialect=database_dialect,
@@ -156,7 +156,7 @@ async def shared_database(
156156
op = await database.update_ddl(ddl_statements=_helpers.DDL_STATEMENTS)
157157
await op.result(database_operation_timeout)
158158
else:
159-
database = shared_instance.database(
159+
database = await shared_instance.database(
160160
database_name,
161161
ddl_statements=_helpers.DDL_STATEMENTS,
162162
pool=pool,

tests/system/_async/test_database_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ async def test_table_not_found(shared_instance):
3636
)
3737
create_index = f"CREATE INDEX IDX ON {incorrect_table} (Field1)"
3838

39-
temp_db = shared_instance.database(
39+
temp_db = await shared_instance.database(
4040
temp_db_id, ddl_statements=[create_table, create_index]
4141
)
4242
with pytest.raises(exceptions.NotFound):
@@ -55,7 +55,7 @@ async def test_list_databases(shared_instance, shared_database):
5555
async def test_create_database(shared_instance, databases_to_delete, database_dialect):
5656
pool = spanner_v1.AsyncBurstyPool(labels={"testcase": "create_database_async"})
5757
temp_db_id = _helpers.unique_id("temp_db_async")
58-
temp_db = shared_instance.database(
58+
temp_db = await shared_instance.database(
5959
temp_db_id, pool=pool, database_dialect=database_dialect
6060
)
6161
operation = await temp_db.create()

0 commit comments

Comments
 (0)