From 3d3cea0b5afb414a506ab08eebae733d803f17ac Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Wed, 17 Dec 2025 11:11:09 +0530 Subject: [PATCH 1/5] fix: transaction_tag should be set on BeginTransactionRequest (#1463) When using multiplexed sessions, the transaction_tag should also be set on the BeginTransactionRequest. --------- Co-authored-by: rahul2393 --- google/cloud/spanner_v1/snapshot.py | 23 +++++++++++++++++++---- google/cloud/spanner_v1/transaction.py | 4 +++- tests/unit/test_session.py | 5 ++++- tests/unit/test_transaction.py | 1 + 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/google/cloud/spanner_v1/snapshot.py b/google/cloud/spanner_v1/snapshot.py index 46b0f5af8d..89cbc9fe88 100644 --- a/google/cloud/spanner_v1/snapshot.py +++ b/google/cloud/spanner_v1/snapshot.py @@ -901,13 +901,19 @@ def attempt_tracking_method(): return [partition.partition_token for partition in response.partitions] - def _begin_transaction(self, mutation: Mutation = None) -> bytes: + def _begin_transaction( + self, mutation: Mutation = None, transaction_tag: str = None + ) -> bytes: """Begins a transaction on the database. :type mutation: :class:`~google.cloud.spanner_v1.mutation.Mutation` :param mutation: (Optional) Mutation to include in the begin transaction request. Required for mutation-only transactions with multiplexed sessions. + :type transaction_tag: str + :param transaction_tag: (Optional) Transaction tag to include in the begin transaction + request. + :rtype: bytes :returns: identifier for the transaction. @@ -931,6 +937,17 @@ def _begin_transaction(self, mutation: Mutation = None) -> bytes: (_metadata_with_leader_aware_routing(database._route_to_leader_enabled)) ) + begin_request_kwargs = { + "session": session.name, + "options": self._build_transaction_selector_pb().begin, + "mutation_key": mutation, + } + + if transaction_tag: + begin_request_kwargs["request_options"] = RequestOptions( + transaction_tag=transaction_tag + ) + with trace_call( name=f"CloudSpanner.{type(self).__name__}.begin", session=session, @@ -942,9 +959,7 @@ def _begin_transaction(self, mutation: Mutation = None) -> bytes: def wrapped_method(): begin_transaction_request = BeginTransactionRequest( - session=session.name, - options=self._build_transaction_selector_pb().begin, - mutation_key=mutation, + **begin_request_kwargs ) begin_transaction_method = functools.partial( api.begin_transaction, diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index b9e14a0040..de8b421840 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -714,7 +714,9 @@ def _begin_transaction(self, mutation: Mutation = None) -> bytes: if self.rolled_back: raise ValueError("Transaction is already rolled back") - return super(Transaction, self)._begin_transaction(mutation=mutation) + return super(Transaction, self)._begin_transaction( + mutation=mutation, transaction_tag=self.transaction_tag + ) def _begin_mutations_only_transaction(self) -> None: """Begins a mutations-only transaction on the database.""" diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index bfbd6edd5e..8026c50c24 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -2005,9 +2005,12 @@ def unit_of_work(txn, *args, **kw): self.assertEqual(kw, {"some_arg": "def"}) expected_options = TransactionOptions(read_write=TransactionOptions.ReadWrite()) + expected_request_options = RequestOptions(transaction_tag=transaction_tag) gax_api.begin_transaction.assert_called_once_with( request=BeginTransactionRequest( - session=self.SESSION_NAME, options=expected_options + session=self.SESSION_NAME, + options=expected_options, + request_options=expected_request_options, ), metadata=[ ("google-cloud-resource-prefix", database.name), diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 39656cb8d1..510251656e 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -467,6 +467,7 @@ def _commit_helper( session=session.name, options=TransactionOptions(read_write=TransactionOptions.ReadWrite()), mutation_key=expected_begin_mutation, + request_options=RequestOptions(transaction_tag=TRANSACTION_TAG), ) expected_begin_metadata = base_metadata.copy() From 9ec95b7df5e921112bd58b820722103177e0e5b6 Mon Sep 17 00:00:00 2001 From: Subham Sinha <35077434+sinhasubham@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:10:53 +0530 Subject: [PATCH 2/5] fix: resolve pre-release dependency failures and sqlparse recursion (#1472) 1. add cryptography to prerelease dependencies The prerelease dependency check installs packages with `--no-deps`, which causes `google-auth` to fail because its dependency `cryptography` and `cffi` is missing. This change explicitly adds `cryptography` and `cffi` to the `prerel_deps` list in `noxfile.py` to ensure it is installed during the test session. 2. bypass sqlparse for RUN PARTITION commands Check for RUN PARTITION command to avoid sqlparse processing it. sqlparse fails with "Maximum grouping depth exceeded" on long partition IDs causing flakiness in system tests. --- google/cloud/spanner_dbapi/parse_utils.py | 5 +++++ noxfile.py | 3 +++ tests/unit/spanner_dbapi/test_parse_utils.py | 23 ++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/google/cloud/spanner_dbapi/parse_utils.py b/google/cloud/spanner_dbapi/parse_utils.py index 66741eb264..d99caa7e8c 100644 --- a/google/cloud/spanner_dbapi/parse_utils.py +++ b/google/cloud/spanner_dbapi/parse_utils.py @@ -233,6 +233,11 @@ def classify_statement(query, args=None): :rtype: ParsedStatement :returns: parsed statement attributes. """ + # Check for RUN PARTITION command to avoid sqlparse processing it. + # sqlparse fails with "Maximum grouping depth exceeded" on long partition IDs. + if re.match(r"^\s*RUN\s+PARTITION\s+.+", query, re.IGNORECASE): + return client_side_statement_parser.parse_stmt(query.strip()) + # sqlparse will strip Cloud Spanner comments, # still, special commenting styles, like # PostgreSQL dollar quoted comments are not diff --git a/noxfile.py b/noxfile.py index 62d67d0be1..e85fba3c54 100644 --- a/noxfile.py +++ b/noxfile.py @@ -555,6 +555,9 @@ def prerelease_deps(session, protobuf_implementation, database_dialect): "google-cloud-testutils", # dependencies of google-cloud-testutils" "click", + # dependency of google-auth + "cffi", + "cryptography", ] for dep in prerel_deps: diff --git a/tests/unit/spanner_dbapi/test_parse_utils.py b/tests/unit/spanner_dbapi/test_parse_utils.py index f63dbb78e4..ec612d9ebd 100644 --- a/tests/unit/spanner_dbapi/test_parse_utils.py +++ b/tests/unit/spanner_dbapi/test_parse_utils.py @@ -200,6 +200,29 @@ def test_run_partition_classify_stmt(self): ), ) + def test_run_partition_classify_stmt_long_id(self): + # Regression test for "Maximum grouping depth exceeded" with sqlparse + long_id = "a" * 5000 + query = f"RUN PARTITION {long_id}" + parsed_statement = classify_statement(query) + self.assertEqual( + parsed_statement, + ParsedStatement( + StatementType.CLIENT_SIDE, + Statement(query), + ClientSideStatementType.RUN_PARTITION, + [long_id], + ), + ) + + def test_run_partition_classify_stmt_incomplete(self): + # "RUN PARTITION" without ID should be classified as UNKNOWN (not None) + # because it falls through the specific check and sqlparse handles it. + query = "RUN PARTITION" + parsed_statement = classify_statement(query) + self.assertEqual(parsed_statement.statement_type, StatementType.UNKNOWN) + self.assertEqual(parsed_statement.statement.sql, query) + def test_run_partitioned_query_classify_stmt(self): parsed_statement = classify_statement( " RUN PARTITIONED QUERY SELECT s.SongName FROM Songs AS s " From 3b1792aad1d046b6ae1e5c982f5047289dffd95c Mon Sep 17 00:00:00 2001 From: Sri Harsha CH <57220027+harshachinta@users.noreply.github.com> Date: Tue, 6 Jan 2026 19:49:33 +0530 Subject: [PATCH 3/5] feat: add uuid support (#1310) Signed-off-by: Sri Harsha CH Co-authored-by: Subham Sinha --- google/cloud/spanner_v1/_helpers.py | 9 +++++++++ google/cloud/spanner_v1/param_types.py | 1 + google/cloud/spanner_v1/streamed.py | 1 + tests/system/test_session_api.py | 13 +++++++++++++ tests/unit/test__helpers.py | 13 +++++++++++++ 5 files changed, 37 insertions(+) diff --git a/google/cloud/spanner_v1/_helpers.py b/google/cloud/spanner_v1/_helpers.py index aa58c59199..8a200fe812 100644 --- a/google/cloud/spanner_v1/_helpers.py +++ b/google/cloud/spanner_v1/_helpers.py @@ -21,6 +21,7 @@ import base64 import threading import logging +import uuid from google.protobuf.struct_pb2 import ListValue from google.protobuf.struct_pb2 import Value @@ -298,6 +299,8 @@ def _make_value_pb(value): return Value(string_value=base64.b64encode(value)) if isinstance(value, Interval): return Value(string_value=str(value)) + if isinstance(value, uuid.UUID): + return Value(string_value=str(value)) raise ValueError("Unknown type: %s" % (value,)) @@ -399,6 +402,8 @@ def _get_type_decoder(field_type, field_name, column_info=None): return _parse_numeric elif type_code == TypeCode.JSON: return _parse_json + elif type_code == TypeCode.UUID: + return _parse_uuid elif type_code == TypeCode.PROTO: return lambda value_pb: _parse_proto(value_pb, column_info, field_name) elif type_code == TypeCode.ENUM: @@ -481,6 +486,10 @@ def _parse_json(value_pb): return JsonObject.from_str(value_pb.string_value) +def _parse_uuid(value_pb): + return uuid.UUID(value_pb.string_value) + + def _parse_proto(value_pb, column_info, field_name): bytes_value = base64.b64decode(value_pb.string_value) if column_info is not None and column_info.get(field_name) is not None: diff --git a/google/cloud/spanner_v1/param_types.py b/google/cloud/spanner_v1/param_types.py index 72127c0e0b..a5da41601a 100644 --- a/google/cloud/spanner_v1/param_types.py +++ b/google/cloud/spanner_v1/param_types.py @@ -33,6 +33,7 @@ TIMESTAMP = Type(code=TypeCode.TIMESTAMP) NUMERIC = Type(code=TypeCode.NUMERIC) JSON = Type(code=TypeCode.JSON) +UUID = Type(code=TypeCode.UUID) PG_NUMERIC = Type(code=TypeCode.NUMERIC, type_annotation=TypeAnnotationCode.PG_NUMERIC) PG_JSONB = Type(code=TypeCode.JSON, type_annotation=TypeAnnotationCode.PG_JSONB) PG_OID = Type(code=TypeCode.INT64, type_annotation=TypeAnnotationCode.PG_OID) diff --git a/google/cloud/spanner_v1/streamed.py b/google/cloud/spanner_v1/streamed.py index c41e65d39f..e0002141f9 100644 --- a/google/cloud/spanner_v1/streamed.py +++ b/google/cloud/spanner_v1/streamed.py @@ -394,6 +394,7 @@ def _merge_struct(lhs, rhs, type_): TypeCode.PROTO: _merge_string, TypeCode.INTERVAL: _merge_string, TypeCode.ENUM: _merge_string, + TypeCode.UUID: _merge_string, } diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index 2b0caba4e1..96f5cd76dc 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -20,6 +20,7 @@ import struct import threading import time +import uuid import pytest import grpc @@ -3056,6 +3057,18 @@ def test_execute_sql_returning_transfinite_floats(sessions_database, not_postgre assert math.isnan(float_array[2]) +def test_execute_sql_w_uuid_bindings(sessions_database, database_dialect): + if database_dialect == DatabaseDialect.POSTGRESQL: + pytest.skip("UUID parameter type is not yet supported in PostgreSQL dialect.") + _bind_test_helper( + sessions_database, + database_dialect, + spanner_v1.param_types.UUID, + uuid.uuid4(), + [uuid.uuid4(), uuid.uuid4()], + ) + + def test_partition_query(sessions_database, not_emulator, not_experimental_host): row_count = 40 sql = f"SELECT * FROM {_sample_data.TABLE}" diff --git a/tests/unit/test__helpers.py b/tests/unit/test__helpers.py index 40db14607c..8140ecb1be 100644 --- a/tests/unit/test__helpers.py +++ b/tests/unit/test__helpers.py @@ -14,6 +14,7 @@ import unittest +import uuid import mock from opentelemetry.sdk.resources import Resource @@ -786,6 +787,18 @@ def test_w_proto_enum(self): self._callFUT(value_pb, field_type, field_name, column_info), VALUE ) + def test_w_uuid(self): + from google.protobuf.struct_pb2 import Value + from google.cloud.spanner_v1 import Type + from google.cloud.spanner_v1 import TypeCode + + VALUE = uuid.uuid4() + field_type = Type(code=TypeCode.UUID) + field_name = "uuid_column" + value_pb = Value(string_value=str(VALUE)) + + self.assertEqual(self._callFUT(value_pb, field_type, field_name), VALUE) + class Test_parse_list_value_pbs(unittest.TestCase): def _callFUT(self, *args, **kw): From c0668735cb69532f4c852bb7678f63e54da2d34e Mon Sep 17 00:00:00 2001 From: Subham Sinha <35077434+sinhasubham@users.noreply.github.com> Date: Wed, 14 Jan 2026 20:33:02 +0530 Subject: [PATCH 4/5] fix(spanner): handle errors during stream restart in snapshot (#1471) ***Handle errors during stream restart in snapshot*** **Root Cause** When `_restart_on_unavailable` caught a `ServiceUnavailable` or resumable `InternalServerError`, it attempted to re-initialize the iterator immediately within the `except` block. If this re-initialization failed (e.g. due to a persistent transient error), the exception would propagate unhandled, breaking the retry loop. **Fix** This change modifies the logic to reset the iterator to `None` and `continue` the loop, forcing the re-initialization to occur inside the `try` block. This ensures that subsequent errors during restart are properly caught and retried. **Testing** Added unit tests to cover this specific behavior --- google/cloud/spanner_v1/snapshot.py | 54 +++++++---------------------- tests/unit/test_snapshot.py | 50 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/google/cloud/spanner_v1/snapshot.py b/google/cloud/spanner_v1/snapshot.py index 89cbc9fe88..9fa5123119 100644 --- a/google/cloud/spanner_v1/snapshot.py +++ b/google/cloud/spanner_v1/snapshot.py @@ -146,27 +146,12 @@ def _restart_on_unavailable( except ServiceUnavailable: del item_buffer[:] - with trace_call( - trace_name, - session, - attributes, - observability_options=observability_options, - metadata=metadata, - ) as span, MetricsCapture(): - request.resume_token = resume_token - if transaction is not None: - transaction_selector = transaction._build_transaction_selector_pb() - request.transaction = transaction_selector - attempt += 1 - iterator = method( - request=request, - metadata=request_id_manager.metadata_with_request_id( - nth_request, - attempt, - metadata, - span, - ), - ) + request.resume_token = resume_token + if transaction is not None: + transaction_selector = transaction._build_transaction_selector_pb() + request.transaction = transaction_selector + attempt += 1 + iterator = None continue except InternalServerError as exc: @@ -177,27 +162,12 @@ def _restart_on_unavailable( if not resumable_error: raise del item_buffer[:] - with trace_call( - trace_name, - session, - attributes, - observability_options=observability_options, - metadata=metadata, - ) as span, MetricsCapture(): - request.resume_token = resume_token - if transaction is not None: - transaction_selector = transaction._build_transaction_selector_pb() - attempt += 1 - request.transaction = transaction_selector - iterator = method( - request=request, - metadata=request_id_manager.metadata_with_request_id( - nth_request, - attempt, - metadata, - span, - ), - ) + request.resume_token = resume_token + if transaction is not None: + transaction_selector = transaction._build_transaction_selector_pb() + attempt += 1 + request.transaction = transaction_selector + iterator = None continue if len(item_buffer) == 0: diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index 974cc8e75e..f09bd06d1f 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -405,6 +405,56 @@ def test_iteration_w_raw_raising_unavailable_after_token(self): self.assertEqual(request.resume_token, RESUME_TOKEN) self.assertNoSpans() + def test_iteration_w_raw_raising_unavailable_during_restart(self): + from google.api_core.exceptions import ServiceUnavailable + + FIRST = (self._make_item(0), self._make_item(1, resume_token=RESUME_TOKEN)) + LAST = (self._make_item(2),) + before = _MockIterator( + *FIRST, fail_after=True, error=ServiceUnavailable("testing") + ) + after = _MockIterator(*LAST) + request = mock.Mock(test="test", spec=["test", "resume_token"]) + # The second call (the first retry) raises ServiceUnavailable immediately. + # The third call (the second retry) succeeds. + restart = mock.Mock( + spec=[], + side_effect=[before, ServiceUnavailable("retry failed"), after], + ) + database = _Database() + database.spanner_api = build_spanner_api() + session = _Session(database) + derived = _build_snapshot_derived(session) + resumable = self._call_fut(derived, restart, request, session=session) + self.assertEqual(list(resumable), list(FIRST + LAST)) + self.assertEqual(len(restart.mock_calls), 3) + self.assertEqual(request.resume_token, RESUME_TOKEN) + self.assertNoSpans() + + def test_iteration_w_raw_raising_resumable_internal_error_during_restart(self): + FIRST = (self._make_item(0), self._make_item(1, resume_token=RESUME_TOKEN)) + LAST = (self._make_item(2),) + before = _MockIterator( + *FIRST, + fail_after=True, + error=INTERNAL_SERVER_ERROR_UNEXPECTED_EOS, + ) + after = _MockIterator(*LAST) + request = mock.Mock(test="test", spec=["test", "resume_token"]) + restart = mock.Mock( + spec=[], + side_effect=[before, INTERNAL_SERVER_ERROR_UNEXPECTED_EOS, after], + ) + database = _Database() + database.spanner_api = build_spanner_api() + session = _Session(database) + derived = _build_snapshot_derived(session) + resumable = self._call_fut(derived, restart, request, session=session) + self.assertEqual(list(resumable), list(FIRST + LAST)) + self.assertEqual(len(restart.mock_calls), 3) + self.assertEqual(request.resume_token, RESUME_TOKEN) + self.assertNoSpans() + def test_iteration_w_raw_w_multiuse(self): from google.cloud.spanner_v1 import ( ReadRequest, From f8f3f87df59db8932cca0dfb6add36c92f824695 Mon Sep 17 00:00:00 2001 From: rahul2393 Date: Fri, 16 Jan 2026 11:41:57 +0530 Subject: [PATCH 5/5] chore: librarian release pull request: 20260114T204223Z (#1478) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v1.0.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
google-cloud-spanner: 3.62.0 ## [3.62.0](https://github.com/googleapis/python-spanner/compare/v3.61.0...v3.62.0) (2026-01-14) ### Features * add uuid support (#1310) ([3b1792aa](https://github.com/googleapis/python-spanner/commit/3b1792aa)) ### Bug Fixes * transaction_tag should be set on BeginTransactionRequest (#1463) ([3d3cea0b](https://github.com/googleapis/python-spanner/commit/3d3cea0b)) * resolve pre-release dependency failures and sqlparse recursion (#1472) ([9ec95b7d](https://github.com/googleapis/python-spanner/commit/9ec95b7d)) * handle errors during stream restart in snapshot (#1471) ([c0668735](https://github.com/googleapis/python-spanner/commit/c0668735))
--- .librarian/state.yaml | 2 +- CHANGELOG.md | 14 ++++++++++++++ .../spanner_admin_database_v1/gapic_version.py | 2 +- .../spanner_admin_instance_v1/gapic_version.py | 2 +- google/cloud/spanner_dbapi/version.py | 2 +- google/cloud/spanner_v1/gapic_version.py | 2 +- ..._metadata_google.spanner.admin.database.v1.json | 2 +- ..._metadata_google.spanner.admin.instance.v1.json | 2 +- .../snippet_metadata_google.spanner.v1.json | 2 +- 9 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 381824b372..7dd193bf5b 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,7 +1,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209 libraries: - id: google-cloud-spanner - version: 3.61.0 + version: 3.62.0 last_generated_commit: a17b84add8318f780fcc8a027815d5fee644b9f7 apis: - path: google/spanner/admin/instance/v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 73b4a8d8d3..d29a945636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,20 @@ [1]: https://pypi.org/project/google-cloud-spanner/#history +## [3.62.0](https://github.com/googleapis/python-spanner/compare/v3.61.0...v3.62.0) (2026-01-14) + + +### Features + +* add uuid support (#1310) ([3b1792aad1d046b6ae1e5c982f5047289dffd95c](https://github.com/googleapis/python-spanner/commit/3b1792aad1d046b6ae1e5c982f5047289dffd95c)) + + +### Bug Fixes + +* handle errors during stream restart in snapshot (#1471) ([c0668735cb69532f4c852bb7678f63e54da2d34e](https://github.com/googleapis/python-spanner/commit/c0668735cb69532f4c852bb7678f63e54da2d34e)) +* resolve pre-release dependency failures and sqlparse recursion (#1472) ([9ec95b7df5e921112bd58b820722103177e0e5b6](https://github.com/googleapis/python-spanner/commit/9ec95b7df5e921112bd58b820722103177e0e5b6)) +* transaction_tag should be set on BeginTransactionRequest (#1463) ([3d3cea0b5afb414a506ab08eebae733d803f17ac](https://github.com/googleapis/python-spanner/commit/3d3cea0b5afb414a506ab08eebae733d803f17ac)) + ## [3.61.0](https://github.com/googleapis/python-spanner/compare/v3.60.0...v3.61.0) (2025-12-16) diff --git a/google/cloud/spanner_admin_database_v1/gapic_version.py b/google/cloud/spanner_admin_database_v1/gapic_version.py index 89cb359ff2..b548ea04d7 100644 --- a/google/cloud/spanner_admin_database_v1/gapic_version.py +++ b/google/cloud/spanner_admin_database_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.61.0" # {x-release-please-version} +__version__ = "3.62.0" # {x-release-please-version} diff --git a/google/cloud/spanner_admin_instance_v1/gapic_version.py b/google/cloud/spanner_admin_instance_v1/gapic_version.py index 89cb359ff2..b548ea04d7 100644 --- a/google/cloud/spanner_admin_instance_v1/gapic_version.py +++ b/google/cloud/spanner_admin_instance_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.61.0" # {x-release-please-version} +__version__ = "3.62.0" # {x-release-please-version} diff --git a/google/cloud/spanner_dbapi/version.py b/google/cloud/spanner_dbapi/version.py index 86252a8635..96cdcb4e8e 100644 --- a/google/cloud/spanner_dbapi/version.py +++ b/google/cloud/spanner_dbapi/version.py @@ -15,6 +15,6 @@ import platform PY_VERSION = platform.python_version() -__version__ = "3.61.0" +__version__ = "3.62.0" VERSION = __version__ DEFAULT_USER_AGENT = "gl-dbapi/" + VERSION diff --git a/google/cloud/spanner_v1/gapic_version.py b/google/cloud/spanner_v1/gapic_version.py index 89cb359ff2..b548ea04d7 100644 --- a/google/cloud/spanner_v1/gapic_version.py +++ b/google/cloud/spanner_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.61.0" # {x-release-please-version} +__version__ = "3.62.0" # {x-release-please-version} diff --git a/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json b/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json index 4fd6fa5396..6d18fe5c95 100644 --- a/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json +++ b/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner-admin-database", - "version": "3.61.0" + "version": "3.62.0" }, "snippets": [ { diff --git a/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json b/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json index bae057d766..ee24f85498 100644 --- a/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json +++ b/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner-admin-instance", - "version": "3.61.0" + "version": "3.62.0" }, "snippets": [ { diff --git a/samples/generated_samples/snippet_metadata_google.spanner.v1.json b/samples/generated_samples/snippet_metadata_google.spanner.v1.json index 5148cfa6df..ba41673ed3 100644 --- a/samples/generated_samples/snippet_metadata_google.spanner.v1.json +++ b/samples/generated_samples/snippet_metadata_google.spanner.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner", - "version": "3.61.0" + "version": "3.62.0" }, "snippets": [ {