diff --git a/google/cloud/spanner_v1/services/spanner/async_client.py b/google/cloud/spanner_v1/services/spanner/async_client.py index 7c2e950793..371500333e 100644 --- a/google/cloud/spanner_v1/services/spanner/async_client.py +++ b/google/cloud/spanner_v1/services/spanner/async_client.py @@ -422,7 +422,7 @@ async def sample_batch_create_sessions(): Returns: google.cloud.spanner_v1.types.BatchCreateSessionsResponse: The response for - [BatchCreateSessions][google.spanner.v1.Spanner.BatchCreateSessions]. + [BatchCreateSessions][google.spanner.v1.Spanner.BatchCreateSessions]. """ # Create or coerce a protobuf request object. @@ -1075,8 +1075,10 @@ async def sample_execute_batch_dml(): Returns: google.cloud.spanner_v1.types.ExecuteBatchDmlResponse: - The response for [ExecuteBatchDml][google.spanner.v1.Spanner.ExecuteBatchDml]. Contains a list - of [ResultSet][google.spanner.v1.ResultSet] messages, + The response for + [ExecuteBatchDml][google.spanner.v1.Spanner.ExecuteBatchDml]. + Contains a list of + [ResultSet][google.spanner.v1.ResultSet] messages, one for each DML statement that has successfully executed, in the same order as the statements in the request. If a statement fails, the status in the @@ -1086,34 +1088,35 @@ async def sample_execute_batch_dml(): following approach: 1. Check the status in the response message. The - [google.rpc.Code][google.rpc.Code] enum value OK - indicates that all statements were executed - successfully. - 2. If the status was not OK, check the number of - result sets in the response. If the response - contains N - [ResultSet][google.spanner.v1.ResultSet] messages, - then statement N+1 in the request failed. + [google.rpc.Code][google.rpc.Code] enum value OK + indicates that all statements were executed + successfully. 2. If the status was not OK, check the + number of result sets in the response. If the + response contains N + [ResultSet][google.spanner.v1.ResultSet] messages, + then statement N+1 in the request failed. Example 1: - Request: 5 DML statements, all executed successfully. - - Response: 5 - [ResultSet][google.spanner.v1.ResultSet] messages, - with the status OK. + + \* Response: 5 + [ResultSet][google.spanner.v1.ResultSet] messages, + with the status OK. Example 2: - Request: 5 DML statements. The third statement has a syntax error. - - Response: 2 - [ResultSet][google.spanner.v1.ResultSet] messages, - and a syntax error (INVALID_ARGUMENT) status. The - number of [ResultSet][google.spanner.v1.ResultSet] - messages indicates that the third statement - failed, and the fourth and fifth statements were - not executed. + + \* Response: 2 + [ResultSet][google.spanner.v1.ResultSet] messages, + and a syntax error (INVALID_ARGUMENT) status. The + number of [ResultSet][google.spanner.v1.ResultSet] + messages indicates that the third statement failed, + and the fourth and fifth statements were not + executed. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/spanner_v1/services/spanner/client.py b/google/cloud/spanner_v1/services/spanner/client.py index 03907a1b0b..28f203fff7 100644 --- a/google/cloud/spanner_v1/services/spanner/client.py +++ b/google/cloud/spanner_v1/services/spanner/client.py @@ -669,7 +669,7 @@ def sample_batch_create_sessions(): Returns: google.cloud.spanner_v1.types.BatchCreateSessionsResponse: The response for - [BatchCreateSessions][google.spanner.v1.Spanner.BatchCreateSessions]. + [BatchCreateSessions][google.spanner.v1.Spanner.BatchCreateSessions]. """ # Create or coerce a protobuf request object. @@ -1279,8 +1279,10 @@ def sample_execute_batch_dml(): Returns: google.cloud.spanner_v1.types.ExecuteBatchDmlResponse: - The response for [ExecuteBatchDml][google.spanner.v1.Spanner.ExecuteBatchDml]. Contains a list - of [ResultSet][google.spanner.v1.ResultSet] messages, + The response for + [ExecuteBatchDml][google.spanner.v1.Spanner.ExecuteBatchDml]. + Contains a list of + [ResultSet][google.spanner.v1.ResultSet] messages, one for each DML statement that has successfully executed, in the same order as the statements in the request. If a statement fails, the status in the @@ -1290,34 +1292,35 @@ def sample_execute_batch_dml(): following approach: 1. Check the status in the response message. The - [google.rpc.Code][google.rpc.Code] enum value OK - indicates that all statements were executed - successfully. - 2. If the status was not OK, check the number of - result sets in the response. If the response - contains N - [ResultSet][google.spanner.v1.ResultSet] messages, - then statement N+1 in the request failed. + [google.rpc.Code][google.rpc.Code] enum value OK + indicates that all statements were executed + successfully. 2. If the status was not OK, check the + number of result sets in the response. If the + response contains N + [ResultSet][google.spanner.v1.ResultSet] messages, + then statement N+1 in the request failed. Example 1: - Request: 5 DML statements, all executed successfully. - - Response: 5 - [ResultSet][google.spanner.v1.ResultSet] messages, - with the status OK. + + \* Response: 5 + [ResultSet][google.spanner.v1.ResultSet] messages, + with the status OK. Example 2: - Request: 5 DML statements. The third statement has a syntax error. - - Response: 2 - [ResultSet][google.spanner.v1.ResultSet] messages, - and a syntax error (INVALID_ARGUMENT) status. The - number of [ResultSet][google.spanner.v1.ResultSet] - messages indicates that the third statement - failed, and the fourth and fifth statements were - not executed. + + \* Response: 2 + [ResultSet][google.spanner.v1.ResultSet] messages, + and a syntax error (INVALID_ARGUMENT) status. The + number of [ResultSet][google.spanner.v1.ResultSet] + messages indicates that the third statement failed, + and the fourth and fifth statements were not + executed. """ # Create or coerce a protobuf request object. diff --git a/google/cloud/spanner_v1/types/__init__.py b/google/cloud/spanner_v1/types/__init__.py index f4f619f6c4..52b485d976 100644 --- a/google/cloud/spanner_v1/types/__init__.py +++ b/google/cloud/spanner_v1/types/__init__.py @@ -42,6 +42,7 @@ CommitRequest, CreateSessionRequest, DeleteSessionRequest, + DirectedReadOptions, ExecuteBatchDmlRequest, ExecuteBatchDmlResponse, ExecuteSqlRequest, @@ -89,6 +90,7 @@ "CommitRequest", "CreateSessionRequest", "DeleteSessionRequest", + "DirectedReadOptions", "ExecuteBatchDmlRequest", "ExecuteBatchDmlResponse", "ExecuteSqlRequest", diff --git a/google/cloud/spanner_v1/types/spanner.py b/google/cloud/spanner_v1/types/spanner.py index dfd83ac165..3dbacbe26b 100644 --- a/google/cloud/spanner_v1/types/spanner.py +++ b/google/cloud/spanner_v1/types/spanner.py @@ -41,6 +41,7 @@ "ListSessionsResponse", "DeleteSessionRequest", "RequestOptions", + "DirectedReadOptions", "ExecuteSqlRequest", "ExecuteBatchDmlRequest", "ExecuteBatchDmlResponse", @@ -381,6 +382,150 @@ class Priority(proto.Enum): ) +class DirectedReadOptions(proto.Message): + r"""The DirectedReadOptions can be used to indicate which replicas or + regions should be used for non-transactional reads or queries. + + DirectedReadOptions may only be specified for a read-only + transaction, otherwise the API will return an ``INVALID_ARGUMENT`` + error. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + include_replicas (google.cloud.spanner_v1.types.DirectedReadOptions.IncludeReplicas): + Include_replicas indicates the order of replicas (as they + appear in this list) to process the request. If + auto_failover_disabled is set to true and all replicas are + exhausted without finding a healthy replica, Spanner will + wait for a replica in the list to become available, requests + may fail due to ``DEADLINE_EXCEEDED`` errors. + + This field is a member of `oneof`_ ``replicas``. + exclude_replicas (google.cloud.spanner_v1.types.DirectedReadOptions.ExcludeReplicas): + Exclude_replicas indicates that should be excluded from + serving requests. Spanner will not route requests to the + replicas in this list. + + This field is a member of `oneof`_ ``replicas``. + """ + + class ReplicaSelection(proto.Message): + r"""The directed read replica selector. Callers must provide one or more + of the following fields for replica selection: + + - ``location`` - The location must be one of the regions within the + multi-region configuration of your database. + - ``type`` - The type of the replica. + + Some examples of using replica_selectors are: + + - ``location:us-east1`` --> The "us-east1" replica(s) of any + available type will be used to process the request. + - ``type:READ_ONLY`` --> The "READ_ONLY" type replica(s) in nearest + . available location will be used to process the request. + - ``location:us-east1 type:READ_ONLY`` --> The "READ_ONLY" type + replica(s) in location "us-east1" will be used to process the + request. + + Attributes: + location (str): + The location or region of the serving + requests, e.g. "us-east1". + type_ (google.cloud.spanner_v1.types.DirectedReadOptions.ReplicaSelection.Type): + The type of replica. + """ + + class Type(proto.Enum): + r"""Indicates the type of replica. + + Values: + TYPE_UNSPECIFIED (0): + Not specified. + READ_WRITE (1): + Read-write replicas support both reads and + writes. + READ_ONLY (2): + Read-only replicas only support reads (not + writes). + """ + TYPE_UNSPECIFIED = 0 + READ_WRITE = 1 + READ_ONLY = 2 + + location: str = proto.Field( + proto.STRING, + number=1, + ) + type_: "DirectedReadOptions.ReplicaSelection.Type" = proto.Field( + proto.ENUM, + number=2, + enum="DirectedReadOptions.ReplicaSelection.Type", + ) + + class IncludeReplicas(proto.Message): + r"""An IncludeReplicas contains a repeated set of + ReplicaSelection which indicates the order in which replicas + should be considered. + + Attributes: + replica_selections (MutableSequence[google.cloud.spanner_v1.types.DirectedReadOptions.ReplicaSelection]): + The directed read replica selector. + auto_failover_disabled (bool): + If true, Spanner will not route requests to a replica + outside the include_replicas list when all of the specified + replicas are unavailable or unhealthy. Default value is + ``false``. + """ + + replica_selections: MutableSequence[ + "DirectedReadOptions.ReplicaSelection" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DirectedReadOptions.ReplicaSelection", + ) + auto_failover_disabled: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class ExcludeReplicas(proto.Message): + r"""An ExcludeReplicas contains a repeated set of + ReplicaSelection that should be excluded from serving requests. + + Attributes: + replica_selections (MutableSequence[google.cloud.spanner_v1.types.DirectedReadOptions.ReplicaSelection]): + The directed read replica selector. + """ + + replica_selections: MutableSequence[ + "DirectedReadOptions.ReplicaSelection" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DirectedReadOptions.ReplicaSelection", + ) + + include_replicas: IncludeReplicas = proto.Field( + proto.MESSAGE, + number=1, + oneof="replicas", + message=IncludeReplicas, + ) + exclude_replicas: ExcludeReplicas = proto.Field( + proto.MESSAGE, + number=2, + oneof="replicas", + message=ExcludeReplicas, + ) + + class ExecuteSqlRequest(proto.Message): r"""The request for [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and @@ -481,14 +626,16 @@ class ExecuteSqlRequest(proto.Message): given query. request_options (google.cloud.spanner_v1.types.RequestOptions): Common options for this request. + directed_read_options (google.cloud.spanner_v1.types.DirectedReadOptions): + Directed read options for this request. data_boost_enabled (bool): If this is for a partitioned query and this field is set to - ``true``, the request will be executed via Spanner + ``true``, the request is executed with Spanner Data Boost independent compute resources. If the field is set to ``true`` but the request does not set - ``partition_token``, the API will return an - ``INVALID_ARGUMENT`` error. + ``partition_token``, the API returns an ``INVALID_ARGUMENT`` + error. """ class QueryMode(proto.Enum): @@ -628,6 +775,11 @@ class QueryOptions(proto.Message): number=11, message="RequestOptions", ) + directed_read_options: "DirectedReadOptions" = proto.Field( + proto.MESSAGE, + number=15, + message="DirectedReadOptions", + ) data_boost_enabled: bool = proto.Field( proto.BOOL, number=16, @@ -870,14 +1022,14 @@ class PartitionQueryRequest(proto.Message): sql (str): Required. The query request to generate partitions for. The request will fail if the query is not root partitionable. - The query plan of a root partitionable query has a single - distributed union operator. A distributed union operator - conceptually divides one or more tables into multiple - splits, remotely evaluates a subquery independently on each - split, and then unions all results. - - This must not contain DML commands, such as INSERT, UPDATE, - or DELETE. Use + For a query to be root partitionable, it needs to satisfy a + few conditions. For example, the first operator in the query + execution plan must be a distributed union operator. For + more information about other conditions, see `Read data in + parallel `__. + + The query request must not contain DML commands, such as + INSERT, UPDATE, or DELETE. Use [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] with a PartitionedDml transaction for large, partition-friendly DML operations. @@ -1142,14 +1294,16 @@ class ReadRequest(proto.Message): create this partition_token. request_options (google.cloud.spanner_v1.types.RequestOptions): Common options for this request. + directed_read_options (google.cloud.spanner_v1.types.DirectedReadOptions): + Directed read options for this request. data_boost_enabled (bool): If this is for a partitioned read and this field is set to - ``true``, the request will be executed via Spanner + ``true``, the request is executed with Spanner Data Boost independent compute resources. If the field is set to ``true`` but the request does not set - ``partition_token``, the API will return an - ``INVALID_ARGUMENT`` error. + ``partition_token``, the API returns an ``INVALID_ARGUMENT`` + error. """ session: str = proto.Field( @@ -1195,6 +1349,11 @@ class ReadRequest(proto.Message): number=11, message="RequestOptions", ) + directed_read_options: "DirectedReadOptions" = proto.Field( + proto.MESSAGE, + number=14, + message="DirectedReadOptions", + ) data_boost_enabled: bool = proto.Field( proto.BOOL, number=15, diff --git a/scripts/fixup_spanner_v1_keywords.py b/scripts/fixup_spanner_v1_keywords.py index b1ba4084df..f79f70b2dd 100644 --- a/scripts/fixup_spanner_v1_keywords.py +++ b/scripts/fixup_spanner_v1_keywords.py @@ -46,15 +46,15 @@ class spannerCallTransformer(cst.CSTTransformer): 'create_session': ('database', 'session', ), 'delete_session': ('name', ), 'execute_batch_dml': ('session', 'transaction', 'statements', 'seqno', 'request_options', ), - 'execute_sql': ('session', 'sql', 'transaction', 'params', 'param_types', 'resume_token', 'query_mode', 'partition_token', 'seqno', 'query_options', 'request_options', 'data_boost_enabled', ), - 'execute_streaming_sql': ('session', 'sql', 'transaction', 'params', 'param_types', 'resume_token', 'query_mode', 'partition_token', 'seqno', 'query_options', 'request_options', 'data_boost_enabled', ), + 'execute_sql': ('session', 'sql', 'transaction', 'params', 'param_types', 'resume_token', 'query_mode', 'partition_token', 'seqno', 'query_options', 'request_options', 'directed_read_options', 'data_boost_enabled', ), + 'execute_streaming_sql': ('session', 'sql', 'transaction', 'params', 'param_types', 'resume_token', 'query_mode', 'partition_token', 'seqno', 'query_options', 'request_options', 'directed_read_options', 'data_boost_enabled', ), 'get_session': ('name', ), 'list_sessions': ('database', 'page_size', 'page_token', 'filter', ), 'partition_query': ('session', 'sql', 'transaction', 'params', 'param_types', 'partition_options', ), 'partition_read': ('session', 'table', 'key_set', 'transaction', 'index', 'columns', 'partition_options', ), - 'read': ('session', 'table', 'columns', 'key_set', 'transaction', 'index', 'limit', 'resume_token', 'partition_token', 'request_options', 'data_boost_enabled', ), + 'read': ('session', 'table', 'columns', 'key_set', 'transaction', 'index', 'limit', 'resume_token', 'partition_token', 'request_options', 'directed_read_options', 'data_boost_enabled', ), 'rollback': ('session', 'transaction_id', ), - 'streaming_read': ('session', 'table', 'columns', 'key_set', 'transaction', 'index', 'limit', 'resume_token', 'partition_token', 'request_options', 'data_boost_enabled', ), + 'streaming_read': ('session', 'table', 'columns', 'key_set', 'transaction', 'index', 'limit', 'resume_token', 'partition_token', 'request_options', 'directed_read_options', 'data_boost_enabled', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: