google-cloud-spanner 3.51.0__tar.gz → 3.52.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {google_cloud_spanner-3.51.0/google_cloud_spanner.egg-info → google_cloud_spanner-3.52.0}/PKG-INFO +2 -1
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/gapic_version.py +1 -1
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/gapic_version.py +1 -1
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/connection.py +32 -3
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/cursor.py +39 -3
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/parse_utils.py +1 -1
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/transaction_helper.py +1 -1
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/_helpers.py +123 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/_opentelemetry_tracing.py +37 -5
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/batch.py +25 -5
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/database.py +176 -108
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/gapic_version.py +1 -1
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/merged_result_set.py +12 -0
- google_cloud_spanner-3.52.0/google/cloud/spanner_v1/metrics/constants.py +63 -0
- google_cloud_spanner-3.52.0/google/cloud/spanner_v1/metrics/metrics_exporter.py +392 -0
- google_cloud_spanner-3.52.0/google/cloud/spanner_v1/metrics/metrics_tracer.py +558 -0
- google_cloud_spanner-3.52.0/google/cloud/spanner_v1/metrics/metrics_tracer_factory.py +309 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/pool.py +192 -26
- google_cloud_spanner-3.52.0/google/cloud/spanner_v1/request_id_header.py +42 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/session.py +124 -97
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/snapshot.py +20 -11
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/testing/mock_spanner.py +62 -14
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/transaction.py +65 -39
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0/google_cloud_spanner.egg-info}/PKG-INFO +2 -1
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google_cloud_spanner.egg-info/SOURCES.txt +11 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google_cloud_spanner.egg-info/requires.txt +1 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/setup.py +1 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/_helpers.py +61 -4
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/mockserver_tests/mock_server_test_base.py +52 -0
- google_cloud_spanner-3.52.0/tests/mockserver_tests/test_aborted_transaction.py +143 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/mockserver_tests/test_basics.py +22 -0
- google_cloud_spanner-3.52.0/tests/mockserver_tests/test_tags.py +206 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/_helpers.py +18 -0
- google_cloud_spanner-3.52.0/tests/system/test_observability_options.py +454 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/test_session_api.py +73 -38
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_parse_utils.py +5 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test__helpers.py +60 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test__opentelemetry_tracing.py +73 -0
- google_cloud_spanner-3.52.0/tests/unit/test_atomic_counter.py +78 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_batch.py +54 -7
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_database.py +12 -5
- google_cloud_spanner-3.52.0/tests/unit/test_metric_exporter.py +488 -0
- google_cloud_spanner-3.52.0/tests/unit/test_metrics_tracer.py +224 -0
- google_cloud_spanner-3.52.0/tests/unit/test_metrics_tracer_factory.py +59 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_pool.py +404 -184
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_session.py +56 -5
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_snapshot.py +40 -22
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_spanner.py +4 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_transaction.py +99 -10
- google_cloud_spanner-3.51.0/tests/system/test_observability_options.py +0 -134
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/LICENSE +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/MANIFEST.in +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/README.rst +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/gapic_metadata.json +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/py.typed +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/pagers.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/base.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc_asyncio.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/rest.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/rest_base.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/types/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/types/backup.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/types/backup_schedule.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/types/common.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_database_v1/types/spanner_database_admin.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/gapic_metadata.json +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/py.typed +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/pagers.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/base.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc_asyncio.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest_base.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/types/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/types/common.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_admin_instance_v1/types/spanner_instance_admin.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/_helpers.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/batch_dml_executor.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/checksum.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/client_side_statement_executor.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/client_side_statement_parser.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/exceptions.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/parsed_statement.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/parser.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/partition_helper.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/types.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/utils.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/version.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/backup.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/data_types.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/gapic_metadata.json +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/instance.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/keyset.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/param_types.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/py.typed +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/async_client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/pagers.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/transports/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/transports/base.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/transports/grpc.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/transports/rest.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/services/spanner/transports/rest_base.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/streamed.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/table.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/testing/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/testing/database_test.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/testing/interceptors.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/testing/mock_database_admin.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/testing/spanner_database_admin_pb2_grpc.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/testing/spanner_pb2_grpc.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/commit_response.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/keys.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/mutation.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/query_plan.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/result_set.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/spanner.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/transaction.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/types/type.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google_cloud_spanner.egg-info/dependency_links.txt +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google_cloud_spanner.egg-info/not-zip-safe +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google_cloud_spanner.egg-info/top_level.txt +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/setup.cfg +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/_fixtures.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/mockserver_tests/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/_sample_data.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/conftest.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/test_backup_api.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/test_database_api.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/test_dbapi.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/test_instance_api.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/test_streaming_chunking.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/test_table_api.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/testdata/descriptors.pb +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/testdata/singer.proto +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/testdata/singer_pb2.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/utils/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/utils/clear_streaming.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/utils/populate_streaming.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/utils/scrub_instances.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/system/utils/streaming_utils.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/gapic/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/gapic/spanner_admin_database_v1/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/gapic/spanner_admin_instance_v1/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/gapic/spanner_v1/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/gapic/spanner_v1/test_spanner.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/__init__.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test__helpers.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_batch_dml_executor.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_checksum.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_connect.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_connection.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_cursor.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_globals.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_parser.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_transaction_helper.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_types.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/spanner_dbapi/test_utils.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/streaming-read-acceptance-test.json +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_backup.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_client.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_datatypes.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_instance.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_keyset.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_packaging.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_param_types.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_streamed.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/test_table.py +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/testdata/singer.proto +0 -0
- {google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/tests/unit/testdata/singer_pb2.py +0 -0
{google_cloud_spanner-3.51.0/google_cloud_spanner.egg-info → google_cloud_spanner-3.52.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: google-cloud-spanner
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.52.0
|
|
4
4
|
Summary: Google Cloud Spanner API client library
|
|
5
5
|
Home-page: https://github.com/googleapis/python-spanner
|
|
6
6
|
Author: Google LLC
|
|
@@ -34,6 +34,7 @@ Provides-Extra: tracing
|
|
|
34
34
|
Requires-Dist: opentelemetry-api>=1.22.0; extra == "tracing"
|
|
35
35
|
Requires-Dist: opentelemetry-sdk>=1.22.0; extra == "tracing"
|
|
36
36
|
Requires-Dist: opentelemetry-semantic-conventions>=0.43b0; extra == "tracing"
|
|
37
|
+
Requires-Dist: google-cloud-monitoring>=2.16.0; extra == "tracing"
|
|
37
38
|
Provides-Extra: libcst
|
|
38
39
|
Requires-Dist: libcst>=0.2.5; extra == "libcst"
|
|
39
40
|
|
{google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/connection.py
RENAMED
|
@@ -113,7 +113,7 @@ class Connection:
|
|
|
113
113
|
self.request_priority = None
|
|
114
114
|
self._transaction_begin_marked = False
|
|
115
115
|
# whether transaction started at Spanner. This means that we had
|
|
116
|
-
# made
|
|
116
|
+
# made at least one call to Spanner.
|
|
117
117
|
self._spanner_transaction_started = False
|
|
118
118
|
self._batch_mode = BatchMode.NONE
|
|
119
119
|
self._batch_dml_executor: BatchDmlExecutor = None
|
|
@@ -261,6 +261,28 @@ class Connection:
|
|
|
261
261
|
self.request_priority = None
|
|
262
262
|
return req_opts
|
|
263
263
|
|
|
264
|
+
@property
|
|
265
|
+
def transaction_tag(self):
|
|
266
|
+
"""The transaction tag that will be applied to the next read/write
|
|
267
|
+
transaction on this `Connection`. This property is automatically cleared
|
|
268
|
+
when a new transaction is started.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
str: The transaction tag that will be applied to the next read/write transaction.
|
|
272
|
+
"""
|
|
273
|
+
return self._connection_variables.get("transaction_tag", None)
|
|
274
|
+
|
|
275
|
+
@transaction_tag.setter
|
|
276
|
+
def transaction_tag(self, value):
|
|
277
|
+
"""Sets the transaction tag for the next read/write transaction on this
|
|
278
|
+
`Connection`. This property is automatically cleared when a new transaction
|
|
279
|
+
is started.
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
value (str): The transaction tag for the next read/write transaction.
|
|
283
|
+
"""
|
|
284
|
+
self._connection_variables["transaction_tag"] = value
|
|
285
|
+
|
|
264
286
|
@property
|
|
265
287
|
def staleness(self):
|
|
266
288
|
"""Current read staleness option value of this `Connection`.
|
|
@@ -340,6 +362,8 @@ class Connection:
|
|
|
340
362
|
if not self.read_only and self._client_transaction_started:
|
|
341
363
|
if not self._spanner_transaction_started:
|
|
342
364
|
self._transaction = self._session_checkout().transaction()
|
|
365
|
+
self._transaction.transaction_tag = self.transaction_tag
|
|
366
|
+
self.transaction_tag = None
|
|
343
367
|
self._snapshot = None
|
|
344
368
|
self._spanner_transaction_started = True
|
|
345
369
|
self._transaction.begin()
|
|
@@ -458,7 +482,9 @@ class Connection:
|
|
|
458
482
|
|
|
459
483
|
return self.database.update_ddl(ddl_statements).result()
|
|
460
484
|
|
|
461
|
-
def run_statement(
|
|
485
|
+
def run_statement(
|
|
486
|
+
self, statement: Statement, request_options: RequestOptions = None
|
|
487
|
+
):
|
|
462
488
|
"""Run single SQL statement in begun transaction.
|
|
463
489
|
|
|
464
490
|
This method is never used in autocommit mode. In
|
|
@@ -472,6 +498,9 @@ class Connection:
|
|
|
472
498
|
:param retried: (Optional) Retry the SQL statement if statement
|
|
473
499
|
execution failed. Defaults to false.
|
|
474
500
|
|
|
501
|
+
:type request_options: :class:`RequestOptions`
|
|
502
|
+
:param request_options: Request options to use for this statement.
|
|
503
|
+
|
|
475
504
|
:rtype: :class:`google.cloud.spanner_v1.streamed.StreamedResultSet`,
|
|
476
505
|
:class:`google.cloud.spanner_dbapi.checksum.ResultsChecksum`
|
|
477
506
|
:returns: Streamed result set of the statement and a
|
|
@@ -482,7 +511,7 @@ class Connection:
|
|
|
482
511
|
statement.sql,
|
|
483
512
|
statement.params,
|
|
484
513
|
param_types=statement.param_types,
|
|
485
|
-
request_options=self.request_options,
|
|
514
|
+
request_options=request_options or self.request_options,
|
|
486
515
|
)
|
|
487
516
|
|
|
488
517
|
@check_not_closed
|
{google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_dbapi/cursor.py
RENAMED
|
@@ -50,6 +50,7 @@ from google.cloud.spanner_dbapi.parsed_statement import (
|
|
|
50
50
|
from google.cloud.spanner_dbapi.transaction_helper import CursorStatementType
|
|
51
51
|
from google.cloud.spanner_dbapi.utils import PeekIterator
|
|
52
52
|
from google.cloud.spanner_dbapi.utils import StreamedManyResultSets
|
|
53
|
+
from google.cloud.spanner_v1 import RequestOptions
|
|
53
54
|
from google.cloud.spanner_v1.merged_result_set import MergedResultSet
|
|
54
55
|
|
|
55
56
|
ColumnDetails = namedtuple("column_details", ["null_ok", "spanner_type"])
|
|
@@ -97,6 +98,39 @@ class Cursor(object):
|
|
|
97
98
|
self._parsed_statement: ParsedStatement = None
|
|
98
99
|
self._in_retry_mode = False
|
|
99
100
|
self._batch_dml_rows_count = None
|
|
101
|
+
self._request_tag = None
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def request_tag(self):
|
|
105
|
+
"""The request tag that will be applied to the next statement on this
|
|
106
|
+
cursor. This property is automatically cleared when a statement is
|
|
107
|
+
executed.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
str: The request tag that will be applied to the next statement on
|
|
111
|
+
this cursor.
|
|
112
|
+
"""
|
|
113
|
+
return self._request_tag
|
|
114
|
+
|
|
115
|
+
@request_tag.setter
|
|
116
|
+
def request_tag(self, value):
|
|
117
|
+
"""Sets the request tag for the next statement on this cursor. This
|
|
118
|
+
property is automatically cleared when a statement is executed.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
value (str): The request tag for the statement.
|
|
122
|
+
"""
|
|
123
|
+
self._request_tag = value
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def request_options(self):
|
|
127
|
+
options = self.connection.request_options
|
|
128
|
+
if self._request_tag:
|
|
129
|
+
if not options:
|
|
130
|
+
options = RequestOptions()
|
|
131
|
+
options.request_tag = self._request_tag
|
|
132
|
+
self._request_tag = None
|
|
133
|
+
return options
|
|
100
134
|
|
|
101
135
|
@property
|
|
102
136
|
def is_closed(self):
|
|
@@ -284,7 +318,7 @@ class Cursor(object):
|
|
|
284
318
|
sql,
|
|
285
319
|
params=args,
|
|
286
320
|
param_types=self._parsed_statement.statement.param_types,
|
|
287
|
-
request_options=self.
|
|
321
|
+
request_options=self.request_options,
|
|
288
322
|
)
|
|
289
323
|
self._result_set = None
|
|
290
324
|
else:
|
|
@@ -318,7 +352,9 @@ class Cursor(object):
|
|
|
318
352
|
if self.connection._client_transaction_started:
|
|
319
353
|
while True:
|
|
320
354
|
try:
|
|
321
|
-
self._result_set = self.connection.run_statement(
|
|
355
|
+
self._result_set = self.connection.run_statement(
|
|
356
|
+
statement, self.request_options
|
|
357
|
+
)
|
|
322
358
|
self._itr = PeekIterator(self._result_set)
|
|
323
359
|
return
|
|
324
360
|
except Aborted:
|
|
@@ -478,7 +514,7 @@ class Cursor(object):
|
|
|
478
514
|
sql,
|
|
479
515
|
params,
|
|
480
516
|
get_param_types(params),
|
|
481
|
-
request_options=self.
|
|
517
|
+
request_options=self.request_options,
|
|
482
518
|
)
|
|
483
519
|
# Read the first element so that the StreamedResultSet can
|
|
484
520
|
# return the metadata after a DQL statement.
|
|
@@ -155,7 +155,7 @@ STMT_UPDATING = "UPDATING"
|
|
|
155
155
|
STMT_INSERT = "INSERT"
|
|
156
156
|
|
|
157
157
|
# Heuristic for identifying statements that don't need to be run as updates.
|
|
158
|
-
RE_NON_UPDATE = re.compile(r"^\W*(SELECT)", re.IGNORECASE)
|
|
158
|
+
RE_NON_UPDATE = re.compile(r"^\W*(SELECT|GRAPH|FROM)", re.IGNORECASE)
|
|
159
159
|
|
|
160
160
|
RE_WITH = re.compile(r"^\s*(WITH)", re.IGNORECASE)
|
|
161
161
|
|
|
@@ -20,7 +20,7 @@ import time
|
|
|
20
20
|
|
|
21
21
|
from google.cloud.spanner_dbapi.batch_dml_executor import BatchMode
|
|
22
22
|
from google.cloud.spanner_dbapi.exceptions import RetryAborted
|
|
23
|
-
from google.cloud.spanner_v1.
|
|
23
|
+
from google.cloud.spanner_v1._helpers import _get_retry_delay
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
26
|
from google.cloud.spanner_dbapi import Connection, Cursor
|
{google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/_helpers.py
RENAMED
|
@@ -19,6 +19,7 @@ import decimal
|
|
|
19
19
|
import math
|
|
20
20
|
import time
|
|
21
21
|
import base64
|
|
22
|
+
import threading
|
|
22
23
|
|
|
23
24
|
from google.protobuf.struct_pb2 import ListValue
|
|
24
25
|
from google.protobuf.struct_pb2 import Value
|
|
@@ -26,10 +27,15 @@ from google.protobuf.message import Message
|
|
|
26
27
|
from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
|
|
27
28
|
|
|
28
29
|
from google.api_core import datetime_helpers
|
|
30
|
+
from google.api_core.exceptions import Aborted
|
|
29
31
|
from google.cloud._helpers import _date_from_iso8601_date
|
|
30
32
|
from google.cloud.spanner_v1 import TypeCode
|
|
31
33
|
from google.cloud.spanner_v1 import ExecuteSqlRequest
|
|
32
34
|
from google.cloud.spanner_v1 import JsonObject
|
|
35
|
+
from google.cloud.spanner_v1.request_id_header import with_request_id
|
|
36
|
+
from google.rpc.error_details_pb2 import RetryInfo
|
|
37
|
+
|
|
38
|
+
import random
|
|
33
39
|
|
|
34
40
|
# Validation error messages
|
|
35
41
|
NUMERIC_MAX_SCALE_ERR_MSG = (
|
|
@@ -458,11 +464,29 @@ def _metadata_with_prefix(prefix, **kw):
|
|
|
458
464
|
return [("google-cloud-resource-prefix", prefix)]
|
|
459
465
|
|
|
460
466
|
|
|
467
|
+
def _retry_on_aborted_exception(
|
|
468
|
+
func,
|
|
469
|
+
deadline,
|
|
470
|
+
):
|
|
471
|
+
"""
|
|
472
|
+
Handles retry logic for Aborted exceptions, considering the deadline.
|
|
473
|
+
"""
|
|
474
|
+
attempts = 0
|
|
475
|
+
while True:
|
|
476
|
+
try:
|
|
477
|
+
attempts += 1
|
|
478
|
+
return func()
|
|
479
|
+
except Aborted as exc:
|
|
480
|
+
_delay_until_retry(exc, deadline=deadline, attempts=attempts)
|
|
481
|
+
continue
|
|
482
|
+
|
|
483
|
+
|
|
461
484
|
def _retry(
|
|
462
485
|
func,
|
|
463
486
|
retry_count=5,
|
|
464
487
|
delay=2,
|
|
465
488
|
allowed_exceptions=None,
|
|
489
|
+
beforeNextRetry=None,
|
|
466
490
|
):
|
|
467
491
|
"""
|
|
468
492
|
Retry a function with a specified number of retries, delay between retries, and list of allowed exceptions.
|
|
@@ -479,6 +503,9 @@ def _retry(
|
|
|
479
503
|
"""
|
|
480
504
|
retries = 0
|
|
481
505
|
while retries <= retry_count:
|
|
506
|
+
if retries > 0 and beforeNextRetry:
|
|
507
|
+
beforeNextRetry(retries, delay)
|
|
508
|
+
|
|
482
509
|
try:
|
|
483
510
|
return func()
|
|
484
511
|
except Exception as exc:
|
|
@@ -521,3 +548,99 @@ def _metadata_with_leader_aware_routing(value, **kw):
|
|
|
521
548
|
List[Tuple[str, str]]: RPC metadata with leader aware routing header
|
|
522
549
|
"""
|
|
523
550
|
return ("x-goog-spanner-route-to-leader", str(value).lower())
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
def _delay_until_retry(exc, deadline, attempts):
|
|
554
|
+
"""Helper for :meth:`Session.run_in_transaction`.
|
|
555
|
+
|
|
556
|
+
Detect retryable abort, and impose server-supplied delay.
|
|
557
|
+
|
|
558
|
+
:type exc: :class:`google.api_core.exceptions.Aborted`
|
|
559
|
+
:param exc: exception for aborted transaction
|
|
560
|
+
|
|
561
|
+
:type deadline: float
|
|
562
|
+
:param deadline: maximum timestamp to continue retrying the transaction.
|
|
563
|
+
|
|
564
|
+
:type attempts: int
|
|
565
|
+
:param attempts: number of call retries
|
|
566
|
+
"""
|
|
567
|
+
|
|
568
|
+
cause = exc.errors[0]
|
|
569
|
+
now = time.time()
|
|
570
|
+
if now >= deadline:
|
|
571
|
+
raise
|
|
572
|
+
|
|
573
|
+
delay = _get_retry_delay(cause, attempts)
|
|
574
|
+
if delay is not None:
|
|
575
|
+
if now + delay > deadline:
|
|
576
|
+
raise
|
|
577
|
+
|
|
578
|
+
time.sleep(delay)
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
def _get_retry_delay(cause, attempts):
|
|
582
|
+
"""Helper for :func:`_delay_until_retry`.
|
|
583
|
+
|
|
584
|
+
:type exc: :class:`grpc.Call`
|
|
585
|
+
:param exc: exception for aborted transaction
|
|
586
|
+
|
|
587
|
+
:rtype: float
|
|
588
|
+
:returns: seconds to wait before retrying the transaction.
|
|
589
|
+
|
|
590
|
+
:type attempts: int
|
|
591
|
+
:param attempts: number of call retries
|
|
592
|
+
"""
|
|
593
|
+
if hasattr(cause, "trailing_metadata"):
|
|
594
|
+
metadata = dict(cause.trailing_metadata())
|
|
595
|
+
else:
|
|
596
|
+
metadata = {}
|
|
597
|
+
retry_info_pb = metadata.get("google.rpc.retryinfo-bin")
|
|
598
|
+
if retry_info_pb is not None:
|
|
599
|
+
retry_info = RetryInfo()
|
|
600
|
+
retry_info.ParseFromString(retry_info_pb)
|
|
601
|
+
nanos = retry_info.retry_delay.nanos
|
|
602
|
+
return retry_info.retry_delay.seconds + nanos / 1.0e9
|
|
603
|
+
|
|
604
|
+
return 2**attempts + random.random()
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
class AtomicCounter:
|
|
608
|
+
def __init__(self, start_value=0):
|
|
609
|
+
self.__lock = threading.Lock()
|
|
610
|
+
self.__value = start_value
|
|
611
|
+
|
|
612
|
+
@property
|
|
613
|
+
def value(self):
|
|
614
|
+
with self.__lock:
|
|
615
|
+
return self.__value
|
|
616
|
+
|
|
617
|
+
def increment(self, n=1):
|
|
618
|
+
with self.__lock:
|
|
619
|
+
self.__value += n
|
|
620
|
+
return self.__value
|
|
621
|
+
|
|
622
|
+
def __iadd__(self, n):
|
|
623
|
+
"""
|
|
624
|
+
Defines the inplace += operator result.
|
|
625
|
+
"""
|
|
626
|
+
with self.__lock:
|
|
627
|
+
self.__value += n
|
|
628
|
+
return self
|
|
629
|
+
|
|
630
|
+
def __add__(self, n):
|
|
631
|
+
"""
|
|
632
|
+
Defines the result of invoking: value = AtomicCounter + addable
|
|
633
|
+
"""
|
|
634
|
+
with self.__lock:
|
|
635
|
+
n += self.__value
|
|
636
|
+
return n
|
|
637
|
+
|
|
638
|
+
def __radd__(self, n):
|
|
639
|
+
"""
|
|
640
|
+
Defines the result of invoking: value = addable + AtomicCounter
|
|
641
|
+
"""
|
|
642
|
+
return self.__add__(n)
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
def _metadata_with_request_id(*args, **kwargs):
|
|
646
|
+
return with_request_id(*args, **kwargs)
|
|
@@ -56,11 +56,11 @@ def get_tracer(tracer_provider=None):
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
@contextmanager
|
|
59
|
-
def trace_call(name, session, extra_attributes=None, observability_options=None):
|
|
59
|
+
def trace_call(name, session=None, extra_attributes=None, observability_options=None):
|
|
60
60
|
if session:
|
|
61
61
|
session._last_use_time = datetime.now()
|
|
62
62
|
|
|
63
|
-
if not HAS_OPENTELEMETRY_INSTALLED
|
|
63
|
+
if not (HAS_OPENTELEMETRY_INSTALLED and name):
|
|
64
64
|
# Empty context manager. Users will have to check if the generated value is None or a span
|
|
65
65
|
yield None
|
|
66
66
|
return
|
|
@@ -72,11 +72,16 @@ def trace_call(name, session, extra_attributes=None, observability_options=None)
|
|
|
72
72
|
# on by default.
|
|
73
73
|
enable_extended_tracing = True
|
|
74
74
|
|
|
75
|
+
db_name = ""
|
|
76
|
+
if session and getattr(session, "_database", None):
|
|
77
|
+
db_name = session._database.name
|
|
78
|
+
|
|
75
79
|
if isinstance(observability_options, dict): # Avoid false positives with mock.Mock
|
|
76
80
|
tracer_provider = observability_options.get("tracer_provider", None)
|
|
77
81
|
enable_extended_tracing = observability_options.get(
|
|
78
82
|
"enable_extended_tracing", enable_extended_tracing
|
|
79
83
|
)
|
|
84
|
+
db_name = observability_options.get("db_name", db_name)
|
|
80
85
|
|
|
81
86
|
tracer = get_tracer(tracer_provider)
|
|
82
87
|
|
|
@@ -84,10 +89,14 @@ def trace_call(name, session, extra_attributes=None, observability_options=None)
|
|
|
84
89
|
attributes = {
|
|
85
90
|
"db.type": "spanner",
|
|
86
91
|
"db.url": SpannerClient.DEFAULT_ENDPOINT,
|
|
87
|
-
"db.instance":
|
|
92
|
+
"db.instance": db_name,
|
|
88
93
|
"net.host.name": SpannerClient.DEFAULT_ENDPOINT,
|
|
89
94
|
OTEL_SCOPE_NAME: TRACER_NAME,
|
|
90
95
|
OTEL_SCOPE_VERSION: TRACER_VERSION,
|
|
96
|
+
# Standard GCP attributes for OTel, attributes are used for internal purpose and are subjected to change
|
|
97
|
+
"gcp.client.service": "spanner",
|
|
98
|
+
"gcp.client.version": TRACER_VERSION,
|
|
99
|
+
"gcp.client.repo": "googleapis/python-spanner",
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
if extra_attributes:
|
|
@@ -106,7 +115,30 @@ def trace_call(name, session, extra_attributes=None, observability_options=None)
|
|
|
106
115
|
yield span
|
|
107
116
|
except Exception as error:
|
|
108
117
|
span.set_status(Status(StatusCode.ERROR, str(error)))
|
|
109
|
-
span.record_exception
|
|
118
|
+
# OpenTelemetry-Python imposes invoking span.record_exception on __exit__
|
|
119
|
+
# on any exception. We should file a bug later on with them to only
|
|
120
|
+
# invoke .record_exception if not already invoked, hence we should not
|
|
121
|
+
# invoke .record_exception on our own else we shall have 2 exceptions.
|
|
110
122
|
raise
|
|
111
123
|
else:
|
|
112
|
-
|
|
124
|
+
# All spans still have set_status available even if for example
|
|
125
|
+
# NonRecordingSpan doesn't have "_status".
|
|
126
|
+
absent_span_status = getattr(span, "_status", None) is None
|
|
127
|
+
if absent_span_status or span._status.status_code == StatusCode.UNSET:
|
|
128
|
+
# OpenTelemetry-Python only allows a status change
|
|
129
|
+
# if the current code is UNSET or ERROR. At the end
|
|
130
|
+
# of the generator's consumption, only set it to OK
|
|
131
|
+
# it wasn't previously set otherwise.
|
|
132
|
+
# https://github.com/googleapis/python-spanner/issues/1246
|
|
133
|
+
span.set_status(Status(StatusCode.OK))
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def get_current_span():
|
|
137
|
+
if not HAS_OPENTELEMETRY_INSTALLED:
|
|
138
|
+
return None
|
|
139
|
+
return trace.get_current_span()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def add_span_event(span, event_name, event_attributes=None):
|
|
143
|
+
if span:
|
|
144
|
+
span.add_event(event_name, event_attributes)
|
{google_cloud_spanner-3.51.0 → google_cloud_spanner-3.52.0}/google/cloud/spanner_v1/batch.py
RENAMED
|
@@ -29,8 +29,12 @@ from google.cloud.spanner_v1._helpers import (
|
|
|
29
29
|
from google.cloud.spanner_v1._opentelemetry_tracing import trace_call
|
|
30
30
|
from google.cloud.spanner_v1 import RequestOptions
|
|
31
31
|
from google.cloud.spanner_v1._helpers import _retry
|
|
32
|
+
from google.cloud.spanner_v1._helpers import _retry_on_aborted_exception
|
|
32
33
|
from google.cloud.spanner_v1._helpers import _check_rst_stream_error
|
|
33
34
|
from google.api_core.exceptions import InternalServerError
|
|
35
|
+
import time
|
|
36
|
+
|
|
37
|
+
DEFAULT_RETRY_TIMEOUT_SECS = 30
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
class _BatchBase(_SessionWrapper):
|
|
@@ -70,6 +74,8 @@ class _BatchBase(_SessionWrapper):
|
|
|
70
74
|
:param values: Values to be modified.
|
|
71
75
|
"""
|
|
72
76
|
self._mutations.append(Mutation(insert=_make_write_pb(table, columns, values)))
|
|
77
|
+
# TODO: Decide if we should add a span event per mutation:
|
|
78
|
+
# https://github.com/googleapis/python-spanner/issues/1269
|
|
73
79
|
|
|
74
80
|
def update(self, table, columns, values):
|
|
75
81
|
"""Update one or more existing table rows.
|
|
@@ -84,6 +90,8 @@ class _BatchBase(_SessionWrapper):
|
|
|
84
90
|
:param values: Values to be modified.
|
|
85
91
|
"""
|
|
86
92
|
self._mutations.append(Mutation(update=_make_write_pb(table, columns, values)))
|
|
93
|
+
# TODO: Decide if we should add a span event per mutation:
|
|
94
|
+
# https://github.com/googleapis/python-spanner/issues/1269
|
|
87
95
|
|
|
88
96
|
def insert_or_update(self, table, columns, values):
|
|
89
97
|
"""Insert/update one or more table rows.
|
|
@@ -100,6 +108,8 @@ class _BatchBase(_SessionWrapper):
|
|
|
100
108
|
self._mutations.append(
|
|
101
109
|
Mutation(insert_or_update=_make_write_pb(table, columns, values))
|
|
102
110
|
)
|
|
111
|
+
# TODO: Decide if we should add a span event per mutation:
|
|
112
|
+
# https://github.com/googleapis/python-spanner/issues/1269
|
|
103
113
|
|
|
104
114
|
def replace(self, table, columns, values):
|
|
105
115
|
"""Replace one or more table rows.
|
|
@@ -114,6 +124,8 @@ class _BatchBase(_SessionWrapper):
|
|
|
114
124
|
:param values: Values to be modified.
|
|
115
125
|
"""
|
|
116
126
|
self._mutations.append(Mutation(replace=_make_write_pb(table, columns, values)))
|
|
127
|
+
# TODO: Decide if we should add a span event per mutation:
|
|
128
|
+
# https://github.com/googleapis/python-spanner/issues/1269
|
|
117
129
|
|
|
118
130
|
def delete(self, table, keyset):
|
|
119
131
|
"""Delete one or more table rows.
|
|
@@ -126,6 +138,8 @@ class _BatchBase(_SessionWrapper):
|
|
|
126
138
|
"""
|
|
127
139
|
delete = Mutation.Delete(table=table, key_set=keyset._to_pb())
|
|
128
140
|
self._mutations.append(Mutation(delete=delete))
|
|
141
|
+
# TODO: Decide if we should add a span event per mutation:
|
|
142
|
+
# https://github.com/googleapis/python-spanner/issues/1269
|
|
129
143
|
|
|
130
144
|
|
|
131
145
|
class Batch(_BatchBase):
|
|
@@ -152,6 +166,7 @@ class Batch(_BatchBase):
|
|
|
152
166
|
request_options=None,
|
|
153
167
|
max_commit_delay=None,
|
|
154
168
|
exclude_txn_from_change_streams=False,
|
|
169
|
+
**kwargs,
|
|
155
170
|
):
|
|
156
171
|
"""Commit mutations to the database.
|
|
157
172
|
|
|
@@ -207,7 +222,7 @@ class Batch(_BatchBase):
|
|
|
207
222
|
)
|
|
208
223
|
observability_options = getattr(database, "observability_options", None)
|
|
209
224
|
with trace_call(
|
|
210
|
-
"CloudSpanner.
|
|
225
|
+
f"CloudSpanner.{type(self).__name__}.commit",
|
|
211
226
|
self._session,
|
|
212
227
|
trace_attributes,
|
|
213
228
|
observability_options=observability_options,
|
|
@@ -217,9 +232,12 @@ class Batch(_BatchBase):
|
|
|
217
232
|
request=request,
|
|
218
233
|
metadata=metadata,
|
|
219
234
|
)
|
|
220
|
-
|
|
235
|
+
deadline = time.time() + kwargs.get(
|
|
236
|
+
"timeout_secs", DEFAULT_RETRY_TIMEOUT_SECS
|
|
237
|
+
)
|
|
238
|
+
response = _retry_on_aborted_exception(
|
|
221
239
|
method,
|
|
222
|
-
|
|
240
|
+
deadline=deadline,
|
|
223
241
|
)
|
|
224
242
|
self.committed = response.commit_timestamp
|
|
225
243
|
self.commit_stats = response.commit_stats
|
|
@@ -326,7 +344,7 @@ class MutationGroups(_SessionWrapper):
|
|
|
326
344
|
)
|
|
327
345
|
observability_options = getattr(database, "observability_options", None)
|
|
328
346
|
with trace_call(
|
|
329
|
-
"CloudSpanner.
|
|
347
|
+
"CloudSpanner.batch_write",
|
|
330
348
|
self._session,
|
|
331
349
|
trace_attributes,
|
|
332
350
|
observability_options=observability_options,
|
|
@@ -338,7 +356,9 @@ class MutationGroups(_SessionWrapper):
|
|
|
338
356
|
)
|
|
339
357
|
response = _retry(
|
|
340
358
|
method,
|
|
341
|
-
allowed_exceptions={
|
|
359
|
+
allowed_exceptions={
|
|
360
|
+
InternalServerError: _check_rst_stream_error,
|
|
361
|
+
},
|
|
342
362
|
)
|
|
343
363
|
self.committed = True
|
|
344
364
|
return response
|