From 523b747df9179b6299ad1a100da1489a8ff3c517 Mon Sep 17 00:00:00 2001 From: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> Date: Tue, 2 Mar 2021 16:21:13 +0530 Subject: [PATCH 1/6] feat: Added support for custom timeout and retry parameters in transactions. --- google/cloud/spanner_v1/transaction.py | 15 ++++++++++++--- tests/unit/test_transaction.py | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index aa2353206f..043a22a3bf 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -29,6 +29,8 @@ from google.cloud.spanner_v1.snapshot import _SnapshotBase from google.cloud.spanner_v1.batch import _BatchBase from google.cloud.spanner_v1._opentelemetry_tracing import trace_call +from google.api_core import retry as retries +from google.api_core import gapic_v1 class Transaction(_SnapshotBase, _BatchBase): @@ -185,8 +187,14 @@ def _make_params_pb(params, param_types): return {} def execute_update( - self, dml, params=None, param_types=None, query_mode=None, query_options=None - ): + self, + dml, + params=None, + param_types=None, + query_mode=None, + query_options=None, + retry=gapic_v1.method.DEFAULT, + timeout=None): """Perform an ``ExecuteSql`` API request with DML. :type dml: str @@ -245,7 +253,8 @@ def execute_update( with trace_call( "CloudSpanner.ReadWriteTransaction", self._session, trace_attributes ): - response = api.execute_sql(request=request, metadata=metadata) + response = api.execute_sql( + request=request, metadata=metadata, retry=retry, timeout=timeout) return response.stats.row_count_exact def batch_update(self, statements): diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 4dc56bfa06..56962cb027 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -17,6 +17,8 @@ from tests._helpers import OpenTelemetryBase, StatusCanonicalCode from google.cloud.spanner_v1 import Type from google.cloud.spanner_v1 import TypeCode +from google.api_core import retry as retries +from google.api_core import gapic_v1 TABLE_NAME = "citizens" COLUMNS = ["email", "first_name", "last_name", "age"] @@ -410,7 +412,7 @@ def test_execute_update_w_params_wo_param_types(self): with self.assertRaises(ValueError): transaction.execute_update(DML_QUERY_WITH_PARAM, PARAMS) - def _execute_update_helper(self, count=0, query_options=None): + def _execute_update_helper(self, count=0, query_options=None, retry=gapic_v1.method.DEFAULT, timeout=None): from google.protobuf.struct_pb2 import Struct from google.cloud.spanner_v1 import ( ResultSet, @@ -439,6 +441,8 @@ def _execute_update_helper(self, count=0, query_options=None): PARAM_TYPES, query_mode=MODE, query_options=query_options, + retry=retry, + timeout=timeout, ) self.assertEqual(row_count, 1) @@ -466,6 +470,8 @@ def _execute_update_helper(self, count=0, query_options=None): ) api.execute_sql.assert_called_once_with( request=expected_request, + retry=retry, + timeout=timeout, metadata=[("google-cloud-resource-prefix", database.name)], ) @@ -477,6 +483,15 @@ def test_execute_update_new_transaction(self): def test_execute_update_w_count(self): self._execute_update_helper(count=1) + def test_execute_update_w_timeout_param(self): + self._execute_update_helper(timeout=2.0) + + def test_execute_update_w_retry_param(self): + self._execute_update_helper(retry=gapic_v1.method.DEFAULT) + + def test_execute_update_w_timeout_and_retry_params(self): + self._execute_update_helper(retry=gapic_v1.method.DEFAULT, timeout=2.0) + def test_execute_update_error(self): database = _Database() database.spanner_api = self._make_spanner_api() From 9c1e66fc83c199a1aec794c7fc6324935246333d Mon Sep 17 00:00:00 2001 From: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> Date: Tue, 2 Mar 2021 16:21:13 +0530 Subject: [PATCH 2/6] feat: Added support for custom timeout and retry parameters in transactions --- google/cloud/spanner_v1/transaction.py | 15 ++++++++++++--- tests/unit/test_transaction.py | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index aa2353206f..043a22a3bf 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -29,6 +29,8 @@ from google.cloud.spanner_v1.snapshot import _SnapshotBase from google.cloud.spanner_v1.batch import _BatchBase from google.cloud.spanner_v1._opentelemetry_tracing import trace_call +from google.api_core import retry as retries +from google.api_core import gapic_v1 class Transaction(_SnapshotBase, _BatchBase): @@ -185,8 +187,14 @@ def _make_params_pb(params, param_types): return {} def execute_update( - self, dml, params=None, param_types=None, query_mode=None, query_options=None - ): + self, + dml, + params=None, + param_types=None, + query_mode=None, + query_options=None, + retry=gapic_v1.method.DEFAULT, + timeout=None): """Perform an ``ExecuteSql`` API request with DML. :type dml: str @@ -245,7 +253,8 @@ def execute_update( with trace_call( "CloudSpanner.ReadWriteTransaction", self._session, trace_attributes ): - response = api.execute_sql(request=request, metadata=metadata) + response = api.execute_sql( + request=request, metadata=metadata, retry=retry, timeout=timeout) return response.stats.row_count_exact def batch_update(self, statements): diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 4dc56bfa06..56962cb027 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -17,6 +17,8 @@ from tests._helpers import OpenTelemetryBase, StatusCanonicalCode from google.cloud.spanner_v1 import Type from google.cloud.spanner_v1 import TypeCode +from google.api_core import retry as retries +from google.api_core import gapic_v1 TABLE_NAME = "citizens" COLUMNS = ["email", "first_name", "last_name", "age"] @@ -410,7 +412,7 @@ def test_execute_update_w_params_wo_param_types(self): with self.assertRaises(ValueError): transaction.execute_update(DML_QUERY_WITH_PARAM, PARAMS) - def _execute_update_helper(self, count=0, query_options=None): + def _execute_update_helper(self, count=0, query_options=None, retry=gapic_v1.method.DEFAULT, timeout=None): from google.protobuf.struct_pb2 import Struct from google.cloud.spanner_v1 import ( ResultSet, @@ -439,6 +441,8 @@ def _execute_update_helper(self, count=0, query_options=None): PARAM_TYPES, query_mode=MODE, query_options=query_options, + retry=retry, + timeout=timeout, ) self.assertEqual(row_count, 1) @@ -466,6 +470,8 @@ def _execute_update_helper(self, count=0, query_options=None): ) api.execute_sql.assert_called_once_with( request=expected_request, + retry=retry, + timeout=timeout, metadata=[("google-cloud-resource-prefix", database.name)], ) @@ -477,6 +483,15 @@ def test_execute_update_new_transaction(self): def test_execute_update_w_count(self): self._execute_update_helper(count=1) + def test_execute_update_w_timeout_param(self): + self._execute_update_helper(timeout=2.0) + + def test_execute_update_w_retry_param(self): + self._execute_update_helper(retry=gapic_v1.method.DEFAULT) + + def test_execute_update_w_timeout_and_retry_params(self): + self._execute_update_helper(retry=gapic_v1.method.DEFAULT, timeout=2.0) + def test_execute_update_error(self): database = _Database() database.spanner_api = self._make_spanner_api() From 44af0dc412cad7fa0a20ed065e5e387575bdc718 Mon Sep 17 00:00:00 2001 From: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> Date: Tue, 2 Mar 2021 18:25:12 +0530 Subject: [PATCH 3/6] docs: added documentation for execute_update method in Transactions file --- google/cloud/spanner_v1/transaction.py | 13 ++++++++++--- tests/unit/test_transaction.py | 5 +++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index 043a22a3bf..4d4567ef6c 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -29,7 +29,6 @@ from google.cloud.spanner_v1.snapshot import _SnapshotBase from google.cloud.spanner_v1.batch import _BatchBase from google.cloud.spanner_v1._opentelemetry_tracing import trace_call -from google.api_core import retry as retries from google.api_core import gapic_v1 @@ -194,7 +193,8 @@ def execute_update( query_mode=None, query_options=None, retry=gapic_v1.method.DEFAULT, - timeout=None): + timeout=None, + ): """Perform an ``ExecuteSql`` API request with DML. :type dml: str @@ -220,6 +220,12 @@ def execute_update( or :class:`dict` :param query_options: (Optional) Options that are provided for query plan stability. + :type retry: :class:`~google.api_core.retry.Retry` + :param retry: (Optional) Designation of what errors, if any, should be retried. + + :type timeout: float + :param timeout: (Optional) The timeout for this request. + :rtype: int :returns: Count of rows affected by the DML statement. """ @@ -254,7 +260,8 @@ def execute_update( "CloudSpanner.ReadWriteTransaction", self._session, trace_attributes ): response = api.execute_sql( - request=request, metadata=metadata, retry=retry, timeout=timeout) + request=request, metadata=metadata, retry=retry, timeout=timeout + ) return response.stats.row_count_exact def batch_update(self, statements): diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 56962cb027..ef7b79e587 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -17,7 +17,6 @@ from tests._helpers import OpenTelemetryBase, StatusCanonicalCode from google.cloud.spanner_v1 import Type from google.cloud.spanner_v1 import TypeCode -from google.api_core import retry as retries from google.api_core import gapic_v1 TABLE_NAME = "citizens" @@ -412,7 +411,9 @@ def test_execute_update_w_params_wo_param_types(self): with self.assertRaises(ValueError): transaction.execute_update(DML_QUERY_WITH_PARAM, PARAMS) - def _execute_update_helper(self, count=0, query_options=None, retry=gapic_v1.method.DEFAULT, timeout=None): + def _execute_update_helper( + self, count=0, query_options=None, retry=gapic_v1.method.DEFAULT, timeout=None + ): from google.protobuf.struct_pb2 import Struct from google.cloud.spanner_v1 import ( ResultSet, From bfb1cbbf77c8676bf7ab5b242ba93a71a78f8091 Mon Sep 17 00:00:00 2001 From: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> Date: Wed, 10 Mar 2021 11:39:46 +0530 Subject: [PATCH 4/6] feat: changed retry and timeout params to keyword only arguments --- google/cloud/spanner_v1/transaction.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index 4d4567ef6c..b203ae085b 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """Spanner read-write transaction support.""" from google.protobuf.struct_pb2 import Struct @@ -192,6 +191,7 @@ def execute_update( param_types=None, query_mode=None, query_options=None, + *, retry=gapic_v1.method.DEFAULT, timeout=None, ): @@ -221,7 +221,7 @@ def execute_update( :param query_options: (Optional) Options that are provided for query plan stability. :type retry: :class:`~google.api_core.retry.Retry` - :param retry: (Optional) Designation of what errors, if any, should be retried. + :param retry: (Optional) The retry settings for this request. :type timeout: float :param timeout: (Optional) The timeout for this request. From 825709dacbf72e4ce9a3303d9d3eb782af7e7273 Mon Sep 17 00:00:00 2001 From: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> Date: Wed, 10 Mar 2021 14:14:46 +0530 Subject: [PATCH 5/6] feat: undo deleted line after license text --- google/cloud/spanner_v1/transaction.py | 1 + 1 file changed, 1 insertion(+) diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index b203ae085b..80c9ec2afe 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """Spanner read-write transaction support.""" from google.protobuf.struct_pb2 import Struct From cdc64e36fe00bde5cdd211a7605399c71047d559 Mon Sep 17 00:00:00 2001 From: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> Date: Thu, 11 Mar 2021 01:59:34 +0530 Subject: [PATCH 6/6] feat: changed default timeout value from None to gapic_v1.method.DEFAULT --- google/cloud/spanner_v1/transaction.py | 2 +- tests/unit/test_transaction.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index 80c9ec2afe..9099d48c46 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -194,7 +194,7 @@ def execute_update( query_options=None, *, retry=gapic_v1.method.DEFAULT, - timeout=None, + timeout=gapic_v1.method.DEFAULT, ): """Perform an ``ExecuteSql`` API request with DML. diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index ef7b79e587..3302f68d2d 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -412,7 +412,11 @@ def test_execute_update_w_params_wo_param_types(self): transaction.execute_update(DML_QUERY_WITH_PARAM, PARAMS) def _execute_update_helper( - self, count=0, query_options=None, retry=gapic_v1.method.DEFAULT, timeout=None + self, + count=0, + query_options=None, + retry=gapic_v1.method.DEFAULT, + timeout=gapic_v1.method.DEFAULT, ): from google.protobuf.struct_pb2 import Struct from google.cloud.spanner_v1 import (