google-cloud-spanner 3.41.0__tar.gz → 3.43.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.41.0/google_cloud_spanner.egg-info → google-cloud-spanner-3.43.0}/PKG-INFO +2 -1
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/gapic_version.py +1 -1
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/spanner_database_admin.py +57 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/gapic_version.py +1 -1
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/_helpers.py +2 -2
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/batch_dml_executor.py +12 -13
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/checksum.py +3 -3
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/client_side_statement_executor.py +4 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/client_side_statement_parser.py +24 -10
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/connection.py +123 -125
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/cursor.py +181 -129
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/parse_utils.py +3 -3
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/parsed_statement.py +7 -3
- google-cloud-spanner-3.43.0/google/cloud/spanner_dbapi/transaction_helper.py +292 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/__init__.py +2 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/batch.py +9 -1
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/database.py +129 -17
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/gapic_version.py +1 -1
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/instance.py +31 -12
- google-cloud-spanner-3.43.0/google/cloud/spanner_v1/merged_result_set.py +133 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/session.py +4 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/snapshot.py +0 -4
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/table.py +55 -13
- google-cloud-spanner-3.43.0/google/cloud/spanner_v1/testing/database_test.py +112 -0
- google-cloud-spanner-3.43.0/google/cloud/spanner_v1/testing/interceptors.py +65 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/transaction.py +26 -7
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/spanner.py +14 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/type.py +22 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0/google_cloud_spanner.egg-info}/PKG-INFO +2 -1
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/SOURCES.txt +5 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/requires.txt +1 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/setup.py +1 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_database_api.py +40 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_dbapi.py +348 -39
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_session_api.py +66 -2
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_table_api.py +1 -1
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py +6 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_connection.py +105 -375
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_cursor.py +227 -260
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_parse_utils.py +28 -0
- google-cloud-spanner-3.43.0/tests/unit/spanner_dbapi/test_transaction_helper.py +621 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_batch.py +45 -9
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_database.py +12 -5
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_snapshot.py +0 -22
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_spanner.py +14 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_table.py +13 -6
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_transaction.py +53 -30
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/LICENSE +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/MANIFEST.in +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/README.rst +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/gapic_metadata.json +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/py.typed +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/pagers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/base.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc_asyncio.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/services/database_admin/transports/rest.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/backup.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_database_v1/types/common.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/gapic_metadata.json +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/py.typed +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/pagers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/base.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc_asyncio.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/types/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/types/common.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_admin_instance_v1/types/spanner_instance_admin.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/exceptions.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/parser.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/partition_helper.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/types.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/utils.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/version.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/_helpers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/_opentelemetry_tracing.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/backup.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/data_types.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/gapic_metadata.json +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/keyset.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/param_types.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/pool.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/py.typed +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/async_client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/pagers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/base.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/grpc.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/services/spanner/transports/rest.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/streamed.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/commit_response.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/keys.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/mutation.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/query_plan.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/result_set.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_v1/types/transaction.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/dependency_links.txt +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/not-zip-safe +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google_cloud_spanner.egg-info/top_level.txt +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/setup.cfg +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/_fixtures.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/_helpers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/_helpers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/_sample_data.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/conftest.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_backup_api.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_instance_api.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/test_streaming_chunking.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/clear_streaming.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/populate_streaming.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/scrub_instances.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/system/utils/streaming_utils.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_database_v1/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_instance_v1/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_v1/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/gapic/spanner_v1/test_spanner.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/__init__.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test__helpers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_batch_dml_executor.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_checksum.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_connect.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_globals.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_parser.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_types.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/spanner_dbapi/test_utils.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/streaming-read-acceptance-test.json +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test__helpers.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test__opentelemetry_tracing.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_backup.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_client.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_instance.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_keyset.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_packaging.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_param_types.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_pool.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_session.py +0 -0
- {google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/tests/unit/test_streamed.py +0 -0
{google-cloud-spanner-3.41.0/google_cloud_spanner.egg-info → google-cloud-spanner-3.43.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.43.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
|
|
@@ -30,6 +30,7 @@ Requires-Dist: sqlparse>=0.4.4
|
|
|
30
30
|
Requires-Dist: proto-plus<2.0.0dev,>=1.22.2; python_version >= "3.11"
|
|
31
31
|
Requires-Dist: protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5
|
|
32
32
|
Requires-Dist: deprecated>=1.2.14
|
|
33
|
+
Requires-Dist: grpc-interceptor>=0.15.4
|
|
33
34
|
Provides-Extra: tracing
|
|
34
35
|
Requires-Dist: opentelemetry-api>=1.1.0; extra == "tracing"
|
|
35
36
|
Requires-Dist: opentelemetry-sdk>=1.1.0; extra == "tracing"
|
|
@@ -355,6 +355,26 @@ class CreateDatabaseRequest(proto.Message):
|
|
|
355
355
|
database_dialect (google.cloud.spanner_admin_database_v1.types.DatabaseDialect):
|
|
356
356
|
Optional. The dialect of the Cloud Spanner
|
|
357
357
|
Database.
|
|
358
|
+
proto_descriptors (bytes):
|
|
359
|
+
Optional. Proto descriptors used by CREATE/ALTER PROTO
|
|
360
|
+
BUNDLE statements in 'extra_statements' above. Contains a
|
|
361
|
+
protobuf-serialized
|
|
362
|
+
`google.protobuf.FileDescriptorSet <https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto>`__.
|
|
363
|
+
To generate it,
|
|
364
|
+
`install <https://grpc.io/docs/protoc-installation/>`__ and
|
|
365
|
+
run ``protoc`` with --include_imports and
|
|
366
|
+
--descriptor_set_out. For example, to generate for
|
|
367
|
+
moon/shot/app.proto, run
|
|
368
|
+
|
|
369
|
+
::
|
|
370
|
+
|
|
371
|
+
$protoc --proto_path=/app_path --proto_path=/lib_path \
|
|
372
|
+
--include_imports \
|
|
373
|
+
--descriptor_set_out=descriptors.data \
|
|
374
|
+
moon/shot/app.proto
|
|
375
|
+
|
|
376
|
+
For more details, see protobuffer `self
|
|
377
|
+
description <https://developers.google.com/protocol-buffers/docs/techniques#self-description>`__.
|
|
358
378
|
"""
|
|
359
379
|
|
|
360
380
|
parent: str = proto.Field(
|
|
@@ -379,6 +399,10 @@ class CreateDatabaseRequest(proto.Message):
|
|
|
379
399
|
number=5,
|
|
380
400
|
enum=common.DatabaseDialect,
|
|
381
401
|
)
|
|
402
|
+
proto_descriptors: bytes = proto.Field(
|
|
403
|
+
proto.BYTES,
|
|
404
|
+
number=6,
|
|
405
|
+
)
|
|
382
406
|
|
|
383
407
|
|
|
384
408
|
class CreateDatabaseMetadata(proto.Message):
|
|
@@ -521,6 +545,25 @@ class UpdateDatabaseDdlRequest(proto.Message):
|
|
|
521
545
|
underscore. If the named operation already exists,
|
|
522
546
|
[UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl]
|
|
523
547
|
returns ``ALREADY_EXISTS``.
|
|
548
|
+
proto_descriptors (bytes):
|
|
549
|
+
Optional. Proto descriptors used by CREATE/ALTER PROTO
|
|
550
|
+
BUNDLE statements. Contains a protobuf-serialized
|
|
551
|
+
`google.protobuf.FileDescriptorSet <https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto>`__.
|
|
552
|
+
To generate it,
|
|
553
|
+
`install <https://grpc.io/docs/protoc-installation/>`__ and
|
|
554
|
+
run ``protoc`` with --include_imports and
|
|
555
|
+
--descriptor_set_out. For example, to generate for
|
|
556
|
+
moon/shot/app.proto, run
|
|
557
|
+
|
|
558
|
+
::
|
|
559
|
+
|
|
560
|
+
$protoc --proto_path=/app_path --proto_path=/lib_path \
|
|
561
|
+
--include_imports \
|
|
562
|
+
--descriptor_set_out=descriptors.data \
|
|
563
|
+
moon/shot/app.proto
|
|
564
|
+
|
|
565
|
+
For more details, see protobuffer `self
|
|
566
|
+
description <https://developers.google.com/protocol-buffers/docs/techniques#self-description>`__.
|
|
524
567
|
"""
|
|
525
568
|
|
|
526
569
|
database: str = proto.Field(
|
|
@@ -535,6 +578,10 @@ class UpdateDatabaseDdlRequest(proto.Message):
|
|
|
535
578
|
proto.STRING,
|
|
536
579
|
number=3,
|
|
537
580
|
)
|
|
581
|
+
proto_descriptors: bytes = proto.Field(
|
|
582
|
+
proto.BYTES,
|
|
583
|
+
number=4,
|
|
584
|
+
)
|
|
538
585
|
|
|
539
586
|
|
|
540
587
|
class DdlStatementActionInfo(proto.Message):
|
|
@@ -682,12 +729,22 @@ class GetDatabaseDdlResponse(proto.Message):
|
|
|
682
729
|
A list of formatted DDL statements defining
|
|
683
730
|
the schema of the database specified in the
|
|
684
731
|
request.
|
|
732
|
+
proto_descriptors (bytes):
|
|
733
|
+
Proto descriptors stored in the database. Contains a
|
|
734
|
+
protobuf-serialized
|
|
735
|
+
`google.protobuf.FileDescriptorSet <https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto>`__.
|
|
736
|
+
For more details, see protobuffer `self
|
|
737
|
+
description <https://developers.google.com/protocol-buffers/docs/techniques#self-description>`__.
|
|
685
738
|
"""
|
|
686
739
|
|
|
687
740
|
statements: MutableSequence[str] = proto.RepeatedField(
|
|
688
741
|
proto.STRING,
|
|
689
742
|
number=1,
|
|
690
743
|
)
|
|
744
|
+
proto_descriptors: bytes = proto.Field(
|
|
745
|
+
proto.BYTES,
|
|
746
|
+
number=2,
|
|
747
|
+
)
|
|
691
748
|
|
|
692
749
|
|
|
693
750
|
class ListDatabaseOperationsRequest(proto.Message):
|
{google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/_helpers.py
RENAMED
|
@@ -18,13 +18,13 @@ from google.cloud.spanner_v1 import param_types
|
|
|
18
18
|
SQL_LIST_TABLES = """
|
|
19
19
|
SELECT table_name
|
|
20
20
|
FROM information_schema.tables
|
|
21
|
-
WHERE table_catalog = '' AND table_schema =
|
|
21
|
+
WHERE table_catalog = '' AND table_schema = @table_schema
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
24
|
SQL_GET_TABLE_COLUMN_SCHEMA = """
|
|
25
25
|
SELECT COLUMN_NAME, IS_NULLABLE, SPANNER_TYPE
|
|
26
26
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
27
|
-
WHERE TABLE_SCHEMA =
|
|
27
|
+
WHERE TABLE_SCHEMA = @table_schema AND TABLE_NAME = @table_name
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
# This table maps spanner_types to Spanner's data type sizes as per
|
|
@@ -16,7 +16,6 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
from enum import Enum
|
|
18
18
|
from typing import TYPE_CHECKING, List
|
|
19
|
-
from google.cloud.spanner_dbapi.checksum import ResultsChecksum
|
|
20
19
|
from google.cloud.spanner_dbapi.parsed_statement import (
|
|
21
20
|
ParsedStatement,
|
|
22
21
|
StatementType,
|
|
@@ -80,8 +79,10 @@ def run_batch_dml(cursor: "Cursor", statements: List[Statement]):
|
|
|
80
79
|
"""
|
|
81
80
|
from google.cloud.spanner_dbapi import OperationalError
|
|
82
81
|
|
|
83
|
-
connection = cursor.connection
|
|
84
82
|
many_result_set = StreamedManyResultSets()
|
|
83
|
+
if not statements:
|
|
84
|
+
return many_result_set
|
|
85
|
+
connection = cursor.connection
|
|
85
86
|
statements_tuple = []
|
|
86
87
|
for statement in statements:
|
|
87
88
|
statements_tuple.append(statement.get_tuple())
|
|
@@ -90,28 +91,26 @@ def run_batch_dml(cursor: "Cursor", statements: List[Statement]):
|
|
|
90
91
|
many_result_set.add_iter(res)
|
|
91
92
|
cursor._row_count = sum([max(val, 0) for val in res])
|
|
92
93
|
else:
|
|
93
|
-
retried = False
|
|
94
94
|
while True:
|
|
95
95
|
try:
|
|
96
96
|
transaction = connection.transaction_checkout()
|
|
97
97
|
status, res = transaction.batch_update(statements_tuple)
|
|
98
|
-
many_result_set.add_iter(res)
|
|
99
|
-
res_checksum = ResultsChecksum()
|
|
100
|
-
res_checksum.consume_result(res)
|
|
101
|
-
res_checksum.consume_result(status.code)
|
|
102
|
-
if not retried:
|
|
103
|
-
connection._statements.append((statements, res_checksum))
|
|
104
|
-
cursor._row_count = sum([max(val, 0) for val in res])
|
|
105
|
-
|
|
106
98
|
if status.code == ABORTED:
|
|
107
99
|
connection._transaction = None
|
|
108
100
|
raise Aborted(status.message)
|
|
109
101
|
elif status.code != OK:
|
|
110
102
|
raise OperationalError(status.message)
|
|
103
|
+
|
|
104
|
+
cursor._batch_dml_rows_count = res
|
|
105
|
+
many_result_set.add_iter(res)
|
|
106
|
+
cursor._row_count = sum([max(val, 0) for val in res])
|
|
111
107
|
return many_result_set
|
|
112
108
|
except Aborted:
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
# We are raising it so it could be handled in transaction_helper.py and is retried
|
|
110
|
+
if cursor._in_retry_mode:
|
|
111
|
+
raise
|
|
112
|
+
else:
|
|
113
|
+
connection._transaction_helper.retry_transaction()
|
|
115
114
|
|
|
116
115
|
|
|
117
116
|
def _do_batch_update(transaction, statements):
|
{google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/checksum.py
RENAMED
|
@@ -62,6 +62,8 @@ class ResultsChecksum:
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
def _compare_checksums(original, retried):
|
|
65
|
+
from google.cloud.spanner_dbapi.transaction_helper import RETRY_ABORTED_ERROR
|
|
66
|
+
|
|
65
67
|
"""Compare the given checksums.
|
|
66
68
|
|
|
67
69
|
Raise an error if the given checksums are not equal.
|
|
@@ -75,6 +77,4 @@ def _compare_checksums(original, retried):
|
|
|
75
77
|
:raises: :exc:`google.cloud.spanner_dbapi.exceptions.RetryAborted` in case if checksums are not equal.
|
|
76
78
|
"""
|
|
77
79
|
if retried != original:
|
|
78
|
-
raise RetryAborted(
|
|
79
|
-
"The transaction was aborted and could not be retried due to a concurrent modification."
|
|
80
|
-
)
|
|
80
|
+
raise RetryAborted(RETRY_ABORTED_ERROR)
|
|
@@ -103,6 +103,10 @@ def execute(cursor: "Cursor", parsed_statement: ParsedStatement):
|
|
|
103
103
|
return connection.run_partition(
|
|
104
104
|
parsed_statement.client_side_statement_params[0]
|
|
105
105
|
)
|
|
106
|
+
if statement_type == ClientSideStatementType.RUN_PARTITIONED_QUERY:
|
|
107
|
+
return connection.run_partitioned_query(parsed_statement)
|
|
108
|
+
if statement_type == ClientSideStatementType.SET_AUTOCOMMIT_DML_MODE:
|
|
109
|
+
return connection._set_autocommit_dml_mode(parsed_statement)
|
|
106
110
|
|
|
107
111
|
|
|
108
112
|
def _get_streamed_result_set(column_name, type_code, column_values):
|
|
@@ -35,6 +35,12 @@ RE_RUN_BATCH = re.compile(r"^\s*(RUN)\s+(BATCH)", re.IGNORECASE)
|
|
|
35
35
|
RE_ABORT_BATCH = re.compile(r"^\s*(ABORT)\s+(BATCH)", re.IGNORECASE)
|
|
36
36
|
RE_PARTITION_QUERY = re.compile(r"^\s*(PARTITION)\s+(.+)", re.IGNORECASE)
|
|
37
37
|
RE_RUN_PARTITION = re.compile(r"^\s*(RUN)\s+(PARTITION)\s+(.+)", re.IGNORECASE)
|
|
38
|
+
RE_RUN_PARTITIONED_QUERY = re.compile(
|
|
39
|
+
r"^\s*(RUN)\s+(PARTITIONED)\s+(QUERY)\s+(.+)", re.IGNORECASE
|
|
40
|
+
)
|
|
41
|
+
RE_SET_AUTOCOMMIT_DML_MODE = re.compile(
|
|
42
|
+
r"^\s*(SET)\s+(AUTOCOMMIT_DML_MODE)\s+(=)\s+(.+)", re.IGNORECASE
|
|
43
|
+
)
|
|
38
44
|
|
|
39
45
|
|
|
40
46
|
def parse_stmt(query):
|
|
@@ -53,28 +59,36 @@ def parse_stmt(query):
|
|
|
53
59
|
client_side_statement_params = []
|
|
54
60
|
if RE_COMMIT.match(query):
|
|
55
61
|
client_side_statement_type = ClientSideStatementType.COMMIT
|
|
56
|
-
|
|
57
|
-
client_side_statement_type = ClientSideStatementType.BEGIN
|
|
58
|
-
if RE_ROLLBACK.match(query):
|
|
62
|
+
elif RE_ROLLBACK.match(query):
|
|
59
63
|
client_side_statement_type = ClientSideStatementType.ROLLBACK
|
|
60
|
-
|
|
64
|
+
elif RE_SHOW_COMMIT_TIMESTAMP.match(query):
|
|
61
65
|
client_side_statement_type = ClientSideStatementType.SHOW_COMMIT_TIMESTAMP
|
|
62
|
-
|
|
66
|
+
elif RE_SHOW_READ_TIMESTAMP.match(query):
|
|
63
67
|
client_side_statement_type = ClientSideStatementType.SHOW_READ_TIMESTAMP
|
|
64
|
-
|
|
68
|
+
elif RE_START_BATCH_DML.match(query):
|
|
65
69
|
client_side_statement_type = ClientSideStatementType.START_BATCH_DML
|
|
66
|
-
|
|
70
|
+
elif RE_BEGIN.match(query):
|
|
71
|
+
client_side_statement_type = ClientSideStatementType.BEGIN
|
|
72
|
+
elif RE_RUN_BATCH.match(query):
|
|
67
73
|
client_side_statement_type = ClientSideStatementType.RUN_BATCH
|
|
68
|
-
|
|
74
|
+
elif RE_ABORT_BATCH.match(query):
|
|
69
75
|
client_side_statement_type = ClientSideStatementType.ABORT_BATCH
|
|
70
|
-
|
|
76
|
+
elif RE_RUN_PARTITIONED_QUERY.match(query):
|
|
77
|
+
match = re.search(RE_RUN_PARTITIONED_QUERY, query)
|
|
78
|
+
client_side_statement_params.append(match.group(4))
|
|
79
|
+
client_side_statement_type = ClientSideStatementType.RUN_PARTITIONED_QUERY
|
|
80
|
+
elif RE_PARTITION_QUERY.match(query):
|
|
71
81
|
match = re.search(RE_PARTITION_QUERY, query)
|
|
72
82
|
client_side_statement_params.append(match.group(2))
|
|
73
83
|
client_side_statement_type = ClientSideStatementType.PARTITION_QUERY
|
|
74
|
-
|
|
84
|
+
elif RE_RUN_PARTITION.match(query):
|
|
75
85
|
match = re.search(RE_RUN_PARTITION, query)
|
|
76
86
|
client_side_statement_params.append(match.group(3))
|
|
77
87
|
client_side_statement_type = ClientSideStatementType.RUN_PARTITION
|
|
88
|
+
elif RE_SET_AUTOCOMMIT_DML_MODE.match(query):
|
|
89
|
+
match = re.search(RE_SET_AUTOCOMMIT_DML_MODE, query)
|
|
90
|
+
client_side_statement_params.append(match.group(4))
|
|
91
|
+
client_side_statement_type = ClientSideStatementType.SET_AUTOCOMMIT_DML_MODE
|
|
78
92
|
if client_side_statement_type is not None:
|
|
79
93
|
return ParsedStatement(
|
|
80
94
|
StatementType.CLIENT_SIDE,
|
{google-cloud-spanner-3.41.0 → google-cloud-spanner-3.43.0}/google/cloud/spanner_dbapi/connection.py
RENAMED
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""DB-API Connection for the Google Cloud Spanner."""
|
|
16
|
-
import time
|
|
17
16
|
import warnings
|
|
18
17
|
|
|
19
18
|
from google.api_core.exceptions import Aborted
|
|
@@ -23,19 +22,17 @@ from google.cloud.spanner_dbapi import partition_helper
|
|
|
23
22
|
from google.cloud.spanner_dbapi.batch_dml_executor import BatchMode, BatchDmlExecutor
|
|
24
23
|
from google.cloud.spanner_dbapi.parse_utils import _get_statement_type
|
|
25
24
|
from google.cloud.spanner_dbapi.parsed_statement import (
|
|
26
|
-
ParsedStatement,
|
|
27
|
-
Statement,
|
|
28
25
|
StatementType,
|
|
26
|
+
AutocommitDmlMode,
|
|
29
27
|
)
|
|
30
28
|
from google.cloud.spanner_dbapi.partition_helper import PartitionId
|
|
29
|
+
from google.cloud.spanner_dbapi.parsed_statement import ParsedStatement, Statement
|
|
30
|
+
from google.cloud.spanner_dbapi.transaction_helper import TransactionRetryHelper
|
|
31
|
+
from google.cloud.spanner_dbapi.cursor import Cursor
|
|
31
32
|
from google.cloud.spanner_v1 import RequestOptions
|
|
32
|
-
from google.cloud.spanner_v1.session import _get_retry_delay
|
|
33
33
|
from google.cloud.spanner_v1.snapshot import Snapshot
|
|
34
34
|
from deprecated import deprecated
|
|
35
35
|
|
|
36
|
-
from google.cloud.spanner_dbapi.checksum import _compare_checksums
|
|
37
|
-
from google.cloud.spanner_dbapi.checksum import ResultsChecksum
|
|
38
|
-
from google.cloud.spanner_dbapi.cursor import Cursor
|
|
39
36
|
from google.cloud.spanner_dbapi.exceptions import (
|
|
40
37
|
InterfaceError,
|
|
41
38
|
OperationalError,
|
|
@@ -44,13 +41,10 @@ from google.cloud.spanner_dbapi.exceptions import (
|
|
|
44
41
|
from google.cloud.spanner_dbapi.version import DEFAULT_USER_AGENT
|
|
45
42
|
from google.cloud.spanner_dbapi.version import PY_VERSION
|
|
46
43
|
|
|
47
|
-
from google.rpc.code_pb2 import ABORTED
|
|
48
|
-
|
|
49
44
|
|
|
50
45
|
CLIENT_TRANSACTION_NOT_STARTED_WARNING = (
|
|
51
46
|
"This method is non-operational as a transaction has not been started."
|
|
52
47
|
)
|
|
53
|
-
MAX_INTERNAL_RETRIES = 50
|
|
54
48
|
|
|
55
49
|
|
|
56
50
|
def check_not_closed(function):
|
|
@@ -106,9 +100,6 @@ class Connection:
|
|
|
106
100
|
self._transaction = None
|
|
107
101
|
self._session = None
|
|
108
102
|
self._snapshot = None
|
|
109
|
-
# SQL statements, which were executed
|
|
110
|
-
# within the current transaction
|
|
111
|
-
self._statements = []
|
|
112
103
|
|
|
113
104
|
self.is_closed = False
|
|
114
105
|
self._autocommit = False
|
|
@@ -125,6 +116,27 @@ class Connection:
|
|
|
125
116
|
self._spanner_transaction_started = False
|
|
126
117
|
self._batch_mode = BatchMode.NONE
|
|
127
118
|
self._batch_dml_executor: BatchDmlExecutor = None
|
|
119
|
+
self._transaction_helper = TransactionRetryHelper(self)
|
|
120
|
+
self._autocommit_dml_mode: AutocommitDmlMode = AutocommitDmlMode.TRANSACTIONAL
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def spanner_client(self):
|
|
124
|
+
"""Client for interacting with Cloud Spanner API. This property exposes
|
|
125
|
+
the spanner client so that underlying methods can be accessed.
|
|
126
|
+
"""
|
|
127
|
+
return self._instance._client
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def current_schema(self):
|
|
131
|
+
"""schema name for this connection.
|
|
132
|
+
|
|
133
|
+
:rtype: str
|
|
134
|
+
:returns: the current default schema of this connection. Currently, this
|
|
135
|
+
is always "" for GoogleSQL and "public" for PostgreSQL databases.
|
|
136
|
+
"""
|
|
137
|
+
if self.database is None:
|
|
138
|
+
raise ValueError("database property not set on the connection")
|
|
139
|
+
return self.database.default_schema_name
|
|
128
140
|
|
|
129
141
|
@property
|
|
130
142
|
def autocommit(self):
|
|
@@ -157,6 +169,23 @@ class Connection:
|
|
|
157
169
|
"""
|
|
158
170
|
return self._database
|
|
159
171
|
|
|
172
|
+
@property
|
|
173
|
+
def autocommit_dml_mode(self):
|
|
174
|
+
"""Modes for executing DML statements in autocommit mode for this connection.
|
|
175
|
+
|
|
176
|
+
The DML autocommit modes are:
|
|
177
|
+
1) TRANSACTIONAL - DML statements are executed as single read-write transaction.
|
|
178
|
+
After successful execution, the DML statement is guaranteed to have been applied
|
|
179
|
+
exactly once to the database.
|
|
180
|
+
|
|
181
|
+
2) PARTITIONED_NON_ATOMIC - DML statements are executed as partitioned DML transactions.
|
|
182
|
+
If an error occurs during the execution of the DML statement, it is possible that the
|
|
183
|
+
statement has been applied to some but not all of the rows specified in the statement.
|
|
184
|
+
|
|
185
|
+
:rtype: :class:`~google.cloud.spanner_dbapi.parsed_statement.AutocommitDmlMode`
|
|
186
|
+
"""
|
|
187
|
+
return self._autocommit_dml_mode
|
|
188
|
+
|
|
160
189
|
@property
|
|
161
190
|
@deprecated(
|
|
162
191
|
reason="This method is deprecated. Use _spanner_transaction_started field"
|
|
@@ -282,82 +311,13 @@ class Connection:
|
|
|
282
311
|
|
|
283
312
|
The session will be returned into the sessions pool.
|
|
284
313
|
"""
|
|
314
|
+
if self._session is None:
|
|
315
|
+
return
|
|
285
316
|
if self.database is None:
|
|
286
317
|
raise ValueError("Database needs to be passed for this operation")
|
|
287
|
-
|
|
288
|
-
self.database._pool.put(self._session)
|
|
318
|
+
self.database._pool.put(self._session)
|
|
289
319
|
self._session = None
|
|
290
320
|
|
|
291
|
-
def retry_transaction(self):
|
|
292
|
-
"""Retry the aborted transaction.
|
|
293
|
-
|
|
294
|
-
All the statements executed in the original transaction
|
|
295
|
-
will be re-executed in new one. Results checksums of the
|
|
296
|
-
original statements and the retried ones will be compared.
|
|
297
|
-
|
|
298
|
-
:raises: :class:`google.cloud.spanner_dbapi.exceptions.RetryAborted`
|
|
299
|
-
If results checksum of the retried statement is
|
|
300
|
-
not equal to the checksum of the original one.
|
|
301
|
-
"""
|
|
302
|
-
attempt = 0
|
|
303
|
-
while True:
|
|
304
|
-
self._spanner_transaction_started = False
|
|
305
|
-
attempt += 1
|
|
306
|
-
if attempt > MAX_INTERNAL_RETRIES:
|
|
307
|
-
raise
|
|
308
|
-
|
|
309
|
-
try:
|
|
310
|
-
self._rerun_previous_statements()
|
|
311
|
-
break
|
|
312
|
-
except Aborted as exc:
|
|
313
|
-
delay = _get_retry_delay(exc.errors[0], attempt)
|
|
314
|
-
if delay:
|
|
315
|
-
time.sleep(delay)
|
|
316
|
-
|
|
317
|
-
def _rerun_previous_statements(self):
|
|
318
|
-
"""
|
|
319
|
-
Helper to run all the remembered statements
|
|
320
|
-
from the last transaction.
|
|
321
|
-
"""
|
|
322
|
-
for statement in self._statements:
|
|
323
|
-
if isinstance(statement, list):
|
|
324
|
-
statements, checksum = statement
|
|
325
|
-
|
|
326
|
-
transaction = self.transaction_checkout()
|
|
327
|
-
statements_tuple = []
|
|
328
|
-
for single_statement in statements:
|
|
329
|
-
statements_tuple.append(single_statement.get_tuple())
|
|
330
|
-
status, res = transaction.batch_update(statements_tuple)
|
|
331
|
-
|
|
332
|
-
if status.code == ABORTED:
|
|
333
|
-
raise Aborted(status.details)
|
|
334
|
-
|
|
335
|
-
retried_checksum = ResultsChecksum()
|
|
336
|
-
retried_checksum.consume_result(res)
|
|
337
|
-
retried_checksum.consume_result(status.code)
|
|
338
|
-
|
|
339
|
-
_compare_checksums(checksum, retried_checksum)
|
|
340
|
-
else:
|
|
341
|
-
res_iter, retried_checksum = self.run_statement(statement, retried=True)
|
|
342
|
-
# executing all the completed statements
|
|
343
|
-
if statement != self._statements[-1]:
|
|
344
|
-
for res in res_iter:
|
|
345
|
-
retried_checksum.consume_result(res)
|
|
346
|
-
|
|
347
|
-
_compare_checksums(statement.checksum, retried_checksum)
|
|
348
|
-
# executing the failed statement
|
|
349
|
-
else:
|
|
350
|
-
# streaming up to the failed result or
|
|
351
|
-
# to the end of the streaming iterator
|
|
352
|
-
while len(retried_checksum) < len(statement.checksum):
|
|
353
|
-
try:
|
|
354
|
-
res = next(iter(res_iter))
|
|
355
|
-
retried_checksum.consume_result(res)
|
|
356
|
-
except StopIteration:
|
|
357
|
-
break
|
|
358
|
-
|
|
359
|
-
_compare_checksums(statement.checksum, retried_checksum)
|
|
360
|
-
|
|
361
321
|
def transaction_checkout(self):
|
|
362
322
|
"""Get a Cloud Spanner transaction.
|
|
363
323
|
|
|
@@ -433,12 +393,10 @@ class Connection:
|
|
|
433
393
|
|
|
434
394
|
def commit(self):
|
|
435
395
|
"""Commits any pending transaction to the database.
|
|
436
|
-
|
|
437
396
|
This is a no-op if there is no active client transaction.
|
|
438
397
|
"""
|
|
439
398
|
if self.database is None:
|
|
440
399
|
raise ValueError("Database needs to be passed for this operation")
|
|
441
|
-
|
|
442
400
|
if not self._client_transaction_started:
|
|
443
401
|
warnings.warn(
|
|
444
402
|
CLIENT_TRANSACTION_NOT_STARTED_WARNING, UserWarning, stacklevel=2
|
|
@@ -450,17 +408,13 @@ class Connection:
|
|
|
450
408
|
if self._spanner_transaction_started and not self._read_only:
|
|
451
409
|
self._transaction.commit()
|
|
452
410
|
except Aborted:
|
|
453
|
-
self.retry_transaction()
|
|
411
|
+
self._transaction_helper.retry_transaction()
|
|
454
412
|
self.commit()
|
|
455
413
|
finally:
|
|
456
|
-
self.
|
|
457
|
-
self._statements = []
|
|
458
|
-
self._transaction_begin_marked = False
|
|
459
|
-
self._spanner_transaction_started = False
|
|
414
|
+
self._reset_post_commit_or_rollback()
|
|
460
415
|
|
|
461
416
|
def rollback(self):
|
|
462
417
|
"""Rolls back any pending transaction.
|
|
463
|
-
|
|
464
418
|
This is a no-op if there is no active client transaction.
|
|
465
419
|
"""
|
|
466
420
|
if not self._client_transaction_started:
|
|
@@ -468,15 +422,17 @@ class Connection:
|
|
|
468
422
|
CLIENT_TRANSACTION_NOT_STARTED_WARNING, UserWarning, stacklevel=2
|
|
469
423
|
)
|
|
470
424
|
return
|
|
471
|
-
|
|
472
425
|
try:
|
|
473
426
|
if self._spanner_transaction_started and not self._read_only:
|
|
474
427
|
self._transaction.rollback()
|
|
475
428
|
finally:
|
|
476
|
-
self.
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
429
|
+
self._reset_post_commit_or_rollback()
|
|
430
|
+
|
|
431
|
+
def _reset_post_commit_or_rollback(self):
|
|
432
|
+
self._release_session()
|
|
433
|
+
self._transaction_helper.reset()
|
|
434
|
+
self._transaction_begin_marked = False
|
|
435
|
+
self._spanner_transaction_started = False
|
|
480
436
|
|
|
481
437
|
@check_not_closed
|
|
482
438
|
def cursor(self):
|
|
@@ -493,7 +449,7 @@ class Connection:
|
|
|
493
449
|
|
|
494
450
|
return self.database.update_ddl(ddl_statements).result()
|
|
495
451
|
|
|
496
|
-
def run_statement(self, statement: Statement
|
|
452
|
+
def run_statement(self, statement: Statement):
|
|
497
453
|
"""Run single SQL statement in begun transaction.
|
|
498
454
|
|
|
499
455
|
This method is never used in autocommit mode. In
|
|
@@ -513,17 +469,11 @@ class Connection:
|
|
|
513
469
|
checksum of this statement results.
|
|
514
470
|
"""
|
|
515
471
|
transaction = self.transaction_checkout()
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
statement.sql,
|
|
522
|
-
statement.params,
|
|
523
|
-
param_types=statement.param_types,
|
|
524
|
-
request_options=self.request_options,
|
|
525
|
-
),
|
|
526
|
-
ResultsChecksum() if retried else statement.checksum,
|
|
472
|
+
return transaction.execute_sql(
|
|
473
|
+
statement.sql,
|
|
474
|
+
statement.params,
|
|
475
|
+
param_types=statement.param_types,
|
|
476
|
+
request_options=self.request_options,
|
|
527
477
|
)
|
|
528
478
|
|
|
529
479
|
@check_not_closed
|
|
@@ -600,15 +550,7 @@ class Connection:
|
|
|
600
550
|
):
|
|
601
551
|
statement = parsed_statement.statement
|
|
602
552
|
partitioned_query = parsed_statement.client_side_statement_params[0]
|
|
603
|
-
|
|
604
|
-
raise ProgrammingError(
|
|
605
|
-
"Only queries can be partitioned. Invalid statement: " + statement.sql
|
|
606
|
-
)
|
|
607
|
-
if self.read_only is not True and self._client_transaction_started is True:
|
|
608
|
-
raise ProgrammingError(
|
|
609
|
-
"Partitioned query not supported as the connection is not in "
|
|
610
|
-
"read only mode or ReadWrite transaction started"
|
|
611
|
-
)
|
|
553
|
+
self._partitioned_query_validation(partitioned_query, statement)
|
|
612
554
|
|
|
613
555
|
batch_snapshot = self._database.batch_snapshot()
|
|
614
556
|
partition_ids = []
|
|
@@ -620,17 +562,18 @@ class Connection:
|
|
|
620
562
|
query_options=query_options,
|
|
621
563
|
)
|
|
622
564
|
)
|
|
565
|
+
|
|
566
|
+
batch_transaction_id = batch_snapshot.get_batch_transaction_id()
|
|
623
567
|
for partition in partitions:
|
|
624
|
-
batch_transaction_id = batch_snapshot.get_batch_transaction_id()
|
|
625
568
|
partition_ids.append(
|
|
626
569
|
partition_helper.encode_to_string(batch_transaction_id, partition)
|
|
627
570
|
)
|
|
628
571
|
return partition_ids
|
|
629
572
|
|
|
630
573
|
@check_not_closed
|
|
631
|
-
def run_partition(self,
|
|
574
|
+
def run_partition(self, encoded_partition_id):
|
|
632
575
|
partition_id: PartitionId = partition_helper.decode_from_string(
|
|
633
|
-
|
|
576
|
+
encoded_partition_id
|
|
634
577
|
)
|
|
635
578
|
batch_transaction_id = partition_id.batch_transaction_id
|
|
636
579
|
batch_snapshot = self._database.batch_snapshot(
|
|
@@ -640,6 +583,60 @@ class Connection:
|
|
|
640
583
|
)
|
|
641
584
|
return batch_snapshot.process(partition_id.partition_result)
|
|
642
585
|
|
|
586
|
+
@check_not_closed
|
|
587
|
+
def run_partitioned_query(
|
|
588
|
+
self,
|
|
589
|
+
parsed_statement: ParsedStatement,
|
|
590
|
+
):
|
|
591
|
+
statement = parsed_statement.statement
|
|
592
|
+
partitioned_query = parsed_statement.client_side_statement_params[0]
|
|
593
|
+
self._partitioned_query_validation(partitioned_query, statement)
|
|
594
|
+
batch_snapshot = self._database.batch_snapshot()
|
|
595
|
+
return batch_snapshot.run_partitioned_query(
|
|
596
|
+
partitioned_query, statement.params, statement.param_types
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
@check_not_closed
|
|
600
|
+
def _set_autocommit_dml_mode(
|
|
601
|
+
self,
|
|
602
|
+
parsed_statement: ParsedStatement,
|
|
603
|
+
):
|
|
604
|
+
autocommit_dml_mode_str = parsed_statement.client_side_statement_params[0]
|
|
605
|
+
autocommit_dml_mode = AutocommitDmlMode[autocommit_dml_mode_str.upper()]
|
|
606
|
+
self.set_autocommit_dml_mode(autocommit_dml_mode)
|
|
607
|
+
|
|
608
|
+
def set_autocommit_dml_mode(
|
|
609
|
+
self,
|
|
610
|
+
autocommit_dml_mode,
|
|
611
|
+
):
|
|
612
|
+
"""
|
|
613
|
+
Sets the mode for executing DML statements in autocommit mode for this connection.
|
|
614
|
+
This mode is only used when the connection is in autocommit mode, and may only
|
|
615
|
+
be set while the transaction is in autocommit mode and not in a temporary transaction.
|
|
616
|
+
"""
|
|
617
|
+
|
|
618
|
+
if self._client_transaction_started is True:
|
|
619
|
+
raise ProgrammingError(
|
|
620
|
+
"Cannot set autocommit DML mode while not in autocommit mode or while a transaction is active."
|
|
621
|
+
)
|
|
622
|
+
if self.read_only is True:
|
|
623
|
+
raise ProgrammingError(
|
|
624
|
+
"Cannot set autocommit DML mode for a read-only connection."
|
|
625
|
+
)
|
|
626
|
+
if self._batch_mode is not BatchMode.NONE:
|
|
627
|
+
raise ProgrammingError("Cannot set autocommit DML mode while in a batch.")
|
|
628
|
+
self._autocommit_dml_mode = autocommit_dml_mode
|
|
629
|
+
|
|
630
|
+
def _partitioned_query_validation(self, partitioned_query, statement):
|
|
631
|
+
if _get_statement_type(Statement(partitioned_query)) is not StatementType.QUERY:
|
|
632
|
+
raise ProgrammingError(
|
|
633
|
+
"Only queries can be partitioned. Invalid statement: " + statement.sql
|
|
634
|
+
)
|
|
635
|
+
if self.read_only is not True and self._client_transaction_started is True:
|
|
636
|
+
raise ProgrammingError(
|
|
637
|
+
"Partitioned query is not supported, because the connection is in a read/write transaction."
|
|
638
|
+
)
|
|
639
|
+
|
|
643
640
|
def __enter__(self):
|
|
644
641
|
return self
|
|
645
642
|
|
|
@@ -729,9 +726,10 @@ def connect(
|
|
|
729
726
|
raise ValueError("project in url does not match client object project")
|
|
730
727
|
|
|
731
728
|
instance = client.instance(instance_id)
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
729
|
+
database = None
|
|
730
|
+
if database_id:
|
|
731
|
+
database = instance.database(database_id, pool=pool)
|
|
732
|
+
conn = Connection(instance, database)
|
|
735
733
|
if pool is not None:
|
|
736
734
|
conn._own_pool = False
|
|
737
735
|
|