diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml
index 51b61ba529..757c9dca75 100644
--- a/.github/.OwlBot.lock.yaml
+++ b/.github/.OwlBot.lock.yaml
@@ -13,4 +13,5 @@
# limitations under the License.
docker:
image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest
- digest: sha256:266a3407f0bb34374f49b6556ee20ee819374587246dcc19405b502ec70113b6
+ digest: sha256:81ed5ecdfc7cac5b699ba4537376f3563f6f04122c4ec9e735d3b3dc1d43dd32
+# created: 2022-05-05T22:08:23.383410683Z
diff --git a/.github/auto-approve.yml b/.github/auto-approve.yml
new file mode 100644
index 0000000000..311ebbb853
--- /dev/null
+++ b/.github/auto-approve.yml
@@ -0,0 +1,3 @@
+# https://github.com/googleapis/repo-automation-bots/tree/main/packages/auto-approve
+processes:
+ - "OwlBotTemplateChanges"
diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml
index 8715e17dc4..fc2092ed7f 100644
--- a/.github/blunderbuss.yml
+++ b/.github/blunderbuss.yml
@@ -1,2 +1,2 @@
assign_issues:
- - vi3k6i5
+ - asthamohta
diff --git a/.kokoro/docker/docs/Dockerfile b/.kokoro/docker/docs/Dockerfile
index 4e1b1fb8b5..238b87b9d1 100644
--- a/.kokoro/docker/docs/Dockerfile
+++ b/.kokoro/docker/docs/Dockerfile
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from ubuntu:20.04
+from ubuntu:22.04
ENV DEBIAN_FRONTEND noninteractive
@@ -60,8 +60,24 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/* \
&& rm -f /var/cache/apt/archives/*.deb
+###################### Install python 3.8.11
+
+# Download python 3.8.11
+RUN wget https://www.python.org/ftp/python/3.8.11/Python-3.8.11.tgz
+
+# Extract files
+RUN tar -xvf Python-3.8.11.tgz
+
+# Install python 3.8.11
+RUN ./Python-3.8.11/configure --enable-optimizations
+RUN make altinstall
+
+###################### Install pip
RUN wget -O /tmp/get-pip.py 'https://bootstrap.pypa.io/get-pip.py' \
- && python3.8 /tmp/get-pip.py \
+ && python3 /tmp/get-pip.py \
&& rm /tmp/get-pip.py
+# Test pip
+RUN python3 -m pip
+
CMD ["python3.8"]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 70a1735bb6..62faf8d9cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,18 @@
[1]: https://pypi.org/project/google-cloud-spanner/#history
+## [3.14.1](https://github.com/googleapis/python-spanner/compare/v3.14.0...v3.14.1) (2022-06-08)
+
+
+### Bug Fixes
+
+* **deps:** require protobuf <4.0.0dev ([#731](https://github.com/googleapis/python-spanner/issues/731)) ([8004ae5](https://github.com/googleapis/python-spanner/commit/8004ae54b4a6e6a7b19d8da1de46f3526da881ff))
+
+
+### Documentation
+
+* fix changelog header to consistent size ([#732](https://github.com/googleapis/python-spanner/issues/732)) ([97b6d37](https://github.com/googleapis/python-spanner/commit/97b6d37c78a325c404d649a1db5e7337beedefb5))
+
## [3.14.0](https://github.com/googleapis/python-spanner/compare/v3.13.0...v3.14.0) (2022-04-20)
@@ -40,7 +52,7 @@
* add support for row_count in cursor. ([#675](https://github.com/googleapis/python-spanner/issues/675)) ([d431339](https://github.com/googleapis/python-spanner/commit/d431339069874abf345347b777b3811464925e46))
* resolve DuplicateCredentialArgs error when using credentials_file ([#676](https://github.com/googleapis/python-spanner/issues/676)) ([39ff137](https://github.com/googleapis/python-spanner/commit/39ff13796adc13b6702d003e4d549775f8cef202))
-### [3.12.1](https://www.github.com/googleapis/python-spanner/compare/v3.12.0...v3.12.1) (2022-01-06)
+## [3.12.1](https://www.github.com/googleapis/python-spanner/compare/v3.12.0...v3.12.1) (2022-01-06)
### Bug Fixes
@@ -79,7 +91,7 @@
* list oneofs in docstring ([5ae4be8](https://www.github.com/googleapis/python-spanner/commit/5ae4be8ce0a429b33b31a119d7079ce4deb50ca2))
-### [3.11.1](https://www.github.com/googleapis/python-spanner/compare/v3.11.0...v3.11.1) (2021-10-04)
+## [3.11.1](https://www.github.com/googleapis/python-spanner/compare/v3.11.0...v3.11.1) (2021-10-04)
### Bug Fixes
@@ -330,7 +342,7 @@
* DB-API driver + unit tests ([#160](https://www.github.com/googleapis/python-spanner/issues/160)) ([2493fa1](https://www.github.com/googleapis/python-spanner/commit/2493fa1725d2d613f6c064637a4e215ee66255e3))
* migrate to v2.0.0 ([#147](https://www.github.com/googleapis/python-spanner/issues/147)) ([bf4b278](https://www.github.com/googleapis/python-spanner/commit/bf4b27827494e3dc33b1e4333dfe147a36a486b3))
-### [1.19.1](https://www.github.com/googleapis/python-spanner/compare/v1.19.0...v1.19.1) (2020-10-13)
+## [1.19.1](https://www.github.com/googleapis/python-spanner/compare/v1.19.0...v1.19.1) (2020-10-13)
### Bug Fixes
@@ -377,7 +389,7 @@
* add samples from spanner/cloud-client ([#117](https://www.github.com/googleapis/python-spanner/issues/117)) ([8910771](https://www.github.com/googleapis/python-spanner/commit/891077105d5093a73caf96683d10afef2cd17823)), closes [#804](https://www.github.com/googleapis/python-spanner/issues/804) [#815](https://www.github.com/googleapis/python-spanner/issues/815) [#818](https://www.github.com/googleapis/python-spanner/issues/818) [#887](https://www.github.com/googleapis/python-spanner/issues/887) [#914](https://www.github.com/googleapis/python-spanner/issues/914) [#922](https://www.github.com/googleapis/python-spanner/issues/922) [#928](https://www.github.com/googleapis/python-spanner/issues/928) [#962](https://www.github.com/googleapis/python-spanner/issues/962) [#992](https://www.github.com/googleapis/python-spanner/issues/992) [#1004](https://www.github.com/googleapis/python-spanner/issues/1004) [#1035](https://www.github.com/googleapis/python-spanner/issues/1035) [#1055](https://www.github.com/googleapis/python-spanner/issues/1055) [#1063](https://www.github.com/googleapis/python-spanner/issues/1063) [#1093](https://www.github.com/googleapis/python-spanner/issues/1093) [#1107](https://www.github.com/googleapis/python-spanner/issues/1107) [#1121](https://www.github.com/googleapis/python-spanner/issues/1121) [#1158](https://www.github.com/googleapis/python-spanner/issues/1158) [#1138](https://www.github.com/googleapis/python-spanner/issues/1138) [#1186](https://www.github.com/googleapis/python-spanner/issues/1186) [#1192](https://www.github.com/googleapis/python-spanner/issues/1192) [#1207](https://www.github.com/googleapis/python-spanner/issues/1207) [#1254](https://www.github.com/googleapis/python-spanner/issues/1254) [#1316](https://www.github.com/googleapis/python-spanner/issues/1316) [#1354](https://www.github.com/googleapis/python-spanner/issues/1354) [#1376](https://www.github.com/googleapis/python-spanner/issues/1376) [#1377](https://www.github.com/googleapis/python-spanner/issues/1377) [#1402](https://www.github.com/googleapis/python-spanner/issues/1402) [#1406](https://www.github.com/googleapis/python-spanner/issues/1406) [#1425](https://www.github.com/googleapis/python-spanner/issues/1425) [#1441](https://www.github.com/googleapis/python-spanner/issues/1441) [#1464](https://www.github.com/googleapis/python-spanner/issues/1464) [#1519](https://www.github.com/googleapis/python-spanner/issues/1519) [#1548](https://www.github.com/googleapis/python-spanner/issues/1548) [#1633](https://www.github.com/googleapis/python-spanner/issues/1633) [#1742](https://www.github.com/googleapis/python-spanner/issues/1742) [#1836](https://www.github.com/googleapis/python-spanner/issues/1836) [#1846](https://www.github.com/googleapis/python-spanner/issues/1846) [#1872](https://www.github.com/googleapis/python-spanner/issues/1872) [#1980](https://www.github.com/googleapis/python-spanner/issues/1980) [#2068](https://www.github.com/googleapis/python-spanner/issues/2068) [#2153](https://www.github.com/googleapis/python-spanner/issues/2153) [#2224](https://www.github.com/googleapis/python-spanner/issues/2224) [#2198](https://www.github.com/googleapis/python-spanner/issues/2198) [#2251](https://www.github.com/googleapis/python-spanner/issues/2251) [#2295](https://www.github.com/googleapis/python-spanner/issues/2295) [#2356](https://www.github.com/googleapis/python-spanner/issues/2356) [#2392](https://www.github.com/googleapis/python-spanner/issues/2392) [#2439](https://www.github.com/googleapis/python-spanner/issues/2439) [#2535](https://www.github.com/googleapis/python-spanner/issues/2535) [#2005](https://www.github.com/googleapis/python-spanner/issues/2005) [#2721](https://www.github.com/googleapis/python-spanner/issues/2721) [#3093](https://www.github.com/googleapis/python-spanner/issues/3093) [#3101](https://www.github.com/googleapis/python-spanner/issues/3101) [#2806](https://www.github.com/googleapis/python-spanner/issues/2806) [#3377](https://www.github.com/googleapis/python-spanner/issues/3377)
* typo fix ([#109](https://www.github.com/googleapis/python-spanner/issues/109)) ([63b4324](https://www.github.com/googleapis/python-spanner/commit/63b432472613bd80e234ee9c9f73906db2f0a52b))
-### [1.17.1](https://www.github.com/googleapis/python-spanner/compare/v1.17.0...v1.17.1) (2020-06-24)
+## [1.17.1](https://www.github.com/googleapis/python-spanner/compare/v1.17.0...v1.17.1) (2020-06-24)
### Documentation
@@ -412,7 +424,7 @@
* add keepalive changes to synth.py ([#55](https://www.github.com/googleapis/python-spanner/issues/55)) ([805bbb7](https://www.github.com/googleapis/python-spanner/commit/805bbb766fd9c019f528e2f8ed1379d997622d03))
* pass gRPC config options to gRPC channel creation ([#26](https://www.github.com/googleapis/python-spanner/issues/26)) ([6c9a1ba](https://www.github.com/googleapis/python-spanner/commit/6c9a1badfed610a18454137e1b45156872914e7e))
-### [1.15.1](https://www.github.com/googleapis/python-spanner/compare/v1.15.0...v1.15.1) (2020-04-08)
+## [1.15.1](https://www.github.com/googleapis/python-spanner/compare/v1.15.0...v1.15.1) (2020-04-08)
### Bug Fixes
diff --git a/google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py b/google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py
index c5d38710bf..34989553d5 100644
--- a/google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py
+++ b/google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py
@@ -246,9 +246,9 @@ async def list_databases(
from google.cloud import spanner_admin_database_v1
- def sample_list_databases():
+ async def sample_list_databases():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.ListDatabasesRequest(
@@ -259,7 +259,7 @@ def sample_list_databases():
page_result = client.list_databases(request=request)
# Handle the response
- for response in page_result:
+ async for response in page_result:
print(response)
Args:
@@ -375,9 +375,9 @@ async def create_database(
from google.cloud import spanner_admin_database_v1
- def sample_create_database():
+ async def sample_create_database():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.CreateDatabaseRequest(
@@ -390,7 +390,7 @@ def sample_create_database():
print("Waiting for operation to complete...")
- response = operation.result()
+ response = await operation.result()
# Handle the response
print(response)
@@ -501,9 +501,9 @@ async def get_database(
from google.cloud import spanner_admin_database_v1
- def sample_get_database():
+ async def sample_get_database():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.GetDatabaseRequest(
@@ -511,7 +511,7 @@ def sample_get_database():
)
# Make the request
- response = client.get_database(request=request)
+ response = await client.get_database(request=request)
# Handle the response
print(response)
@@ -614,9 +614,9 @@ async def update_database_ddl(
from google.cloud import spanner_admin_database_v1
- def sample_update_database_ddl():
+ async def sample_update_database_ddl():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.UpdateDatabaseDdlRequest(
@@ -629,7 +629,7 @@ def sample_update_database_ddl():
print("Waiting for operation to complete...")
- response = operation.result()
+ response = await operation.result()
# Handle the response
print(response)
@@ -772,9 +772,9 @@ async def drop_database(
from google.cloud import spanner_admin_database_v1
- def sample_drop_database():
+ async def sample_drop_database():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.DropDatabaseRequest(
@@ -782,7 +782,7 @@ def sample_drop_database():
)
# Make the request
- client.drop_database(request=request)
+ await client.drop_database(request=request)
Args:
request (Union[google.cloud.spanner_admin_database_v1.types.DropDatabaseRequest, dict]):
@@ -866,9 +866,9 @@ async def get_database_ddl(
from google.cloud import spanner_admin_database_v1
- def sample_get_database_ddl():
+ async def sample_get_database_ddl():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.GetDatabaseDdlRequest(
@@ -876,7 +876,7 @@ def sample_get_database_ddl():
)
# Make the request
- response = client.get_database_ddl(request=request)
+ response = await client.get_database_ddl(request=request)
# Handle the response
print(response)
@@ -981,9 +981,9 @@ async def set_iam_policy(
from google.cloud import spanner_admin_database_v1
from google.iam.v1 import iam_policy_pb2 # type: ignore
- def sample_set_iam_policy():
+ async def sample_set_iam_policy():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = iam_policy_pb2.SetIamPolicyRequest(
@@ -991,7 +991,7 @@ def sample_set_iam_policy():
)
# Make the request
- response = client.set_iam_policy(request=request)
+ response = await client.set_iam_policy(request=request)
# Handle the response
print(response)
@@ -1149,9 +1149,9 @@ async def get_iam_policy(
from google.cloud import spanner_admin_database_v1
from google.iam.v1 import iam_policy_pb2 # type: ignore
- def sample_get_iam_policy():
+ async def sample_get_iam_policy():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = iam_policy_pb2.GetIamPolicyRequest(
@@ -1159,7 +1159,7 @@ def sample_get_iam_policy():
)
# Make the request
- response = client.get_iam_policy(request=request)
+ response = await client.get_iam_policy(request=request)
# Handle the response
print(response)
@@ -1328,9 +1328,9 @@ async def test_iam_permissions(
from google.cloud import spanner_admin_database_v1
from google.iam.v1 import iam_policy_pb2 # type: ignore
- def sample_test_iam_permissions():
+ async def sample_test_iam_permissions():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = iam_policy_pb2.TestIamPermissionsRequest(
@@ -1339,7 +1339,7 @@ def sample_test_iam_permissions():
)
# Make the request
- response = client.test_iam_permissions(request=request)
+ response = await client.test_iam_permissions(request=request)
# Handle the response
print(response)
@@ -1450,9 +1450,9 @@ async def create_backup(
from google.cloud import spanner_admin_database_v1
- def sample_create_backup():
+ async def sample_create_backup():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.CreateBackupRequest(
@@ -1465,7 +1465,7 @@ def sample_create_backup():
print("Waiting for operation to complete...")
- response = operation.result()
+ response = await operation.result()
# Handle the response
print(response)
@@ -1599,9 +1599,9 @@ async def copy_backup(
from google.cloud import spanner_admin_database_v1
- def sample_copy_backup():
+ async def sample_copy_backup():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.CopyBackupRequest(
@@ -1615,7 +1615,7 @@ def sample_copy_backup():
print("Waiting for operation to complete...")
- response = operation.result()
+ response = await operation.result()
# Handle the response
print(response)
@@ -1751,9 +1751,9 @@ async def get_backup(
from google.cloud import spanner_admin_database_v1
- def sample_get_backup():
+ async def sample_get_backup():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.GetBackupRequest(
@@ -1761,7 +1761,7 @@ def sample_get_backup():
)
# Make the request
- response = client.get_backup(request=request)
+ response = await client.get_backup(request=request)
# Handle the response
print(response)
@@ -1856,16 +1856,16 @@ async def update_backup(
from google.cloud import spanner_admin_database_v1
- def sample_update_backup():
+ async def sample_update_backup():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.UpdateBackupRequest(
)
# Make the request
- response = client.update_backup(request=request)
+ response = await client.update_backup(request=request)
# Handle the response
print(response)
@@ -1979,9 +1979,9 @@ async def delete_backup(
from google.cloud import spanner_admin_database_v1
- def sample_delete_backup():
+ async def sample_delete_backup():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.DeleteBackupRequest(
@@ -1989,7 +1989,7 @@ def sample_delete_backup():
)
# Make the request
- client.delete_backup(request=request)
+ await client.delete_backup(request=request)
Args:
request (Union[google.cloud.spanner_admin_database_v1.types.DeleteBackupRequest, dict]):
@@ -2075,9 +2075,9 @@ async def list_backups(
from google.cloud import spanner_admin_database_v1
- def sample_list_backups():
+ async def sample_list_backups():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.ListBackupsRequest(
@@ -2088,7 +2088,7 @@ def sample_list_backups():
page_result = client.list_backups(request=request)
# Handle the response
- for response in page_result:
+ async for response in page_result:
print(response)
Args:
@@ -2213,9 +2213,9 @@ async def restore_database(
from google.cloud import spanner_admin_database_v1
- def sample_restore_database():
+ async def sample_restore_database():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.RestoreDatabaseRequest(
@@ -2229,7 +2229,7 @@ def sample_restore_database():
print("Waiting for operation to complete...")
- response = operation.result()
+ response = await operation.result()
# Handle the response
print(response)
@@ -2361,9 +2361,9 @@ async def list_database_operations(
from google.cloud import spanner_admin_database_v1
- def sample_list_database_operations():
+ async def sample_list_database_operations():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.ListDatabaseOperationsRequest(
@@ -2374,7 +2374,7 @@ def sample_list_database_operations():
page_result = client.list_database_operations(request=request)
# Handle the response
- for response in page_result:
+ async for response in page_result:
print(response)
Args:
@@ -2491,9 +2491,9 @@ async def list_backup_operations(
from google.cloud import spanner_admin_database_v1
- def sample_list_backup_operations():
+ async def sample_list_backup_operations():
# Create a client
- client = spanner_admin_database_v1.DatabaseAdminClient()
+ client = spanner_admin_database_v1.DatabaseAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_database_v1.ListBackupOperationsRequest(
@@ -2504,7 +2504,7 @@ def sample_list_backup_operations():
page_result = client.list_backup_operations(request=request)
# Handle the response
- for response in page_result:
+ async for response in page_result:
print(response)
Args:
diff --git a/google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py b/google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py
index 4bbd9558c2..df6936aac3 100644
--- a/google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py
+++ b/google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py
@@ -248,9 +248,9 @@ async def list_instance_configs(
from google.cloud import spanner_admin_instance_v1
- def sample_list_instance_configs():
+ async def sample_list_instance_configs():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_instance_v1.ListInstanceConfigsRequest(
@@ -261,7 +261,7 @@ def sample_list_instance_configs():
page_result = client.list_instance_configs(request=request)
# Handle the response
- for response in page_result:
+ async for response in page_result:
print(response)
Args:
@@ -368,9 +368,9 @@ async def get_instance_config(
from google.cloud import spanner_admin_instance_v1
- def sample_get_instance_config():
+ async def sample_get_instance_config():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_instance_v1.GetInstanceConfigRequest(
@@ -378,7 +378,7 @@ def sample_get_instance_config():
)
# Make the request
- response = client.get_instance_config(request=request)
+ response = await client.get_instance_config(request=request)
# Handle the response
print(response)
@@ -476,9 +476,9 @@ async def list_instances(
from google.cloud import spanner_admin_instance_v1
- def sample_list_instances():
+ async def sample_list_instances():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_instance_v1.ListInstancesRequest(
@@ -489,7 +489,7 @@ def sample_list_instances():
page_result = client.list_instances(request=request)
# Handle the response
- for response in page_result:
+ async for response in page_result:
print(response)
Args:
@@ -595,9 +595,9 @@ async def get_instance(
from google.cloud import spanner_admin_instance_v1
- def sample_get_instance():
+ async def sample_get_instance():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_instance_v1.GetInstanceRequest(
@@ -605,7 +605,7 @@ def sample_get_instance():
)
# Make the request
- response = client.get_instance(request=request)
+ response = await client.get_instance(request=request)
# Handle the response
print(response)
@@ -740,9 +740,9 @@ async def create_instance(
from google.cloud import spanner_admin_instance_v1
- def sample_create_instance():
+ async def sample_create_instance():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
instance = spanner_admin_instance_v1.Instance()
@@ -761,7 +761,7 @@ def sample_create_instance():
print("Waiting for operation to complete...")
- response = operation.result()
+ response = await operation.result()
# Handle the response
print(response)
@@ -923,9 +923,9 @@ async def update_instance(
from google.cloud import spanner_admin_instance_v1
- def sample_update_instance():
+ async def sample_update_instance():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
instance = spanner_admin_instance_v1.Instance()
@@ -942,7 +942,7 @@ def sample_update_instance():
print("Waiting for operation to complete...")
- response = operation.result()
+ response = await operation.result()
# Handle the response
print(response)
@@ -1068,9 +1068,9 @@ async def delete_instance(
from google.cloud import spanner_admin_instance_v1
- def sample_delete_instance():
+ async def sample_delete_instance():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = spanner_admin_instance_v1.DeleteInstanceRequest(
@@ -1078,7 +1078,7 @@ def sample_delete_instance():
)
# Make the request
- client.delete_instance(request=request)
+ await client.delete_instance(request=request)
Args:
request (Union[google.cloud.spanner_admin_instance_v1.types.DeleteInstanceRequest, dict]):
@@ -1167,9 +1167,9 @@ async def set_iam_policy(
from google.cloud import spanner_admin_instance_v1
from google.iam.v1 import iam_policy_pb2 # type: ignore
- def sample_set_iam_policy():
+ async def sample_set_iam_policy():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = iam_policy_pb2.SetIamPolicyRequest(
@@ -1177,7 +1177,7 @@ def sample_set_iam_policy():
)
# Make the request
- response = client.set_iam_policy(request=request)
+ response = await client.set_iam_policy(request=request)
# Handle the response
print(response)
@@ -1331,9 +1331,9 @@ async def get_iam_policy(
from google.cloud import spanner_admin_instance_v1
from google.iam.v1 import iam_policy_pb2 # type: ignore
- def sample_get_iam_policy():
+ async def sample_get_iam_policy():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = iam_policy_pb2.GetIamPolicyRequest(
@@ -1341,7 +1341,7 @@ def sample_get_iam_policy():
)
# Make the request
- response = client.get_iam_policy(request=request)
+ response = await client.get_iam_policy(request=request)
# Handle the response
print(response)
@@ -1507,9 +1507,9 @@ async def test_iam_permissions(
from google.cloud import spanner_admin_instance_v1
from google.iam.v1 import iam_policy_pb2 # type: ignore
- def sample_test_iam_permissions():
+ async def sample_test_iam_permissions():
# Create a client
- client = spanner_admin_instance_v1.InstanceAdminClient()
+ client = spanner_admin_instance_v1.InstanceAdminAsyncClient()
# Initialize request argument(s)
request = iam_policy_pb2.TestIamPermissionsRequest(
@@ -1518,7 +1518,7 @@ def sample_test_iam_permissions():
)
# Make the request
- response = client.test_iam_permissions(request=request)
+ response = await client.test_iam_permissions(request=request)
# Handle the response
print(response)
diff --git a/google/cloud/spanner_dbapi/_helpers.py b/google/cloud/spanner_dbapi/_helpers.py
index 177df9e9bd..ee4883d74f 100644
--- a/google/cloud/spanner_dbapi/_helpers.py
+++ b/google/cloud/spanner_dbapi/_helpers.py
@@ -13,7 +13,6 @@
# limitations under the License.
from google.cloud.spanner_dbapi.parse_utils import get_param_types
-from google.cloud.spanner_dbapi.parse_utils import parse_insert
from google.cloud.spanner_dbapi.parse_utils import sql_pyformat_args_to_spanner
from google.cloud.spanner_v1 import param_types
@@ -51,44 +50,13 @@
def _execute_insert_heterogenous(transaction, sql_params_list):
for sql, params in sql_params_list:
sql, params = sql_pyformat_args_to_spanner(sql, params)
- param_types = get_param_types(params)
- transaction.execute_update(sql, params=params, param_types=param_types)
-
-
-def _execute_insert_homogenous(transaction, parts):
- # Perform an insert in one shot.
- return transaction.insert(
- parts.get("table"), parts.get("columns"), parts.get("values")
- )
+ transaction.execute_update(sql, params, get_param_types(params))
def handle_insert(connection, sql, params):
- parts = parse_insert(sql, params)
-
- # The split between the two styles exists because:
- # in the common case of multiple values being passed
- # with simple pyformat arguments,
- # SQL: INSERT INTO T (f1, f2) VALUES (%s, %s, %s)
- # Params: [(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,)]
- # we can take advantage of a single RPC with:
- # transaction.insert(table, columns, values)
- # instead of invoking:
- # with transaction:
- # for sql, params in sql_params_list:
- # transaction.execute_sql(sql, params, param_types)
- # which invokes more RPCs and is more costly.
-
- if parts.get("homogenous"):
- # The common case of multiple values being passed in
- # non-complex pyformat args and need to be uploaded in one RPC.
- return connection.database.run_in_transaction(_execute_insert_homogenous, parts)
- else:
- # All the other cases that are esoteric and need
- # transaction.execute_sql
- sql_params_list = parts.get("sql_params_list")
- return connection.database.run_in_transaction(
- _execute_insert_heterogenous, sql_params_list
- )
+ return connection.database.run_in_transaction(
+ _execute_insert_heterogenous, ((sql, params),)
+ )
class ColumnInfo:
diff --git a/google/cloud/spanner_dbapi/connection.py b/google/cloud/spanner_dbapi/connection.py
index 76f04338c4..91b63a2da1 100644
--- a/google/cloud/spanner_dbapi/connection.py
+++ b/google/cloud/spanner_dbapi/connection.py
@@ -24,8 +24,6 @@
from google.cloud.spanner_v1.snapshot import Snapshot
from google.cloud.spanner_dbapi._helpers import _execute_insert_heterogenous
-from google.cloud.spanner_dbapi._helpers import _execute_insert_homogenous
-from google.cloud.spanner_dbapi._helpers import parse_insert
from google.cloud.spanner_dbapi.checksum import _compare_checksums
from google.cloud.spanner_dbapi.checksum import ResultsChecksum
from google.cloud.spanner_dbapi.cursor import Cursor
@@ -436,23 +434,13 @@ def run_statement(self, statement, retried=False):
self._statements.append(statement)
if statement.is_insert:
- parts = parse_insert(statement.sql, statement.params)
-
- if parts.get("homogenous"):
- _execute_insert_homogenous(transaction, parts)
- return (
- iter(()),
- ResultsChecksum() if retried else statement.checksum,
- )
- else:
- _execute_insert_heterogenous(
- transaction,
- parts.get("sql_params_list"),
- )
- return (
- iter(()),
- ResultsChecksum() if retried else statement.checksum,
- )
+ _execute_insert_heterogenous(
+ transaction, ((statement.sql, statement.params),)
+ )
+ return (
+ iter(()),
+ ResultsChecksum() if retried else statement.checksum,
+ )
return (
transaction.execute_sql(
diff --git a/google/cloud/spanner_dbapi/parse_utils.py b/google/cloud/spanner_dbapi/parse_utils.py
index 61bded4e80..e051f96a00 100644
--- a/google/cloud/spanner_dbapi/parse_utils.py
+++ b/google/cloud/spanner_dbapi/parse_utils.py
@@ -17,14 +17,12 @@
import datetime
import decimal
import re
-from functools import reduce
import sqlparse
from google.cloud import spanner_v1 as spanner
from google.cloud.spanner_v1 import JsonObject
-from .exceptions import Error, ProgrammingError
-from .parser import expect, VALUES
+from .exceptions import Error
from .types import DateStr, TimestampStr
from .utils import sanitize_literals_for_upload
@@ -185,6 +183,12 @@ def classify_stmt(query):
:rtype: str
:returns: The query type name.
"""
+ # sqlparse will strip Cloud Spanner comments,
+ # still, special commenting styles, like
+ # PostgreSQL dollar quoted comments are not
+ # supported and will not be stripped.
+ query = sqlparse.format(query, strip_comments=True).strip()
+
if RE_DDL.match(query):
return STMT_DDL
@@ -199,255 +203,6 @@ def classify_stmt(query):
return STMT_UPDATING
-def parse_insert(insert_sql, params):
- """
- Parse an INSERT statement and generate a list of tuples of the form:
- [
- (SQL, params_per_row1),
- (SQL, params_per_row2),
- (SQL, params_per_row3),
- ...
- ]
-
- There are 4 variants of an INSERT statement:
- a) INSERT INTO
(columns...) VALUES (): no params
- b) INSERT INTO (columns...) SELECT_STMT: no params
- c) INSERT INTO (columns...) VALUES (%s,...): with params
- d) INSERT INTO (columns...) VALUES (%s,.....) with params and expressions
-
- Thus given each of the forms, it will produce a dictionary describing
- how to upload the contents to Cloud Spanner:
- Case a)
- SQL: INSERT INTO T (f1, f2) VALUES (1, 2)
- it produces:
- {
- 'sql_params_list': [
- ('INSERT INTO T (f1, f2) VALUES (1, 2)', None),
- ],
- }
-
- Case b)
- SQL: 'INSERT INTO T (s, c) SELECT st, zc FROM cus WHERE col IN (%s, %s)',
- it produces:
- {
- 'sql_params_list': [
- ('INSERT INTO T (s, c) SELECT st, zc FROM cus ORDER BY fn, ln', ('a', 'b')),
- ]
- }
-
- Case c)
- SQL: INSERT INTO T (f1, f2) VALUES (%s, %s), (%s, %s)
- Params: ['a', 'b', 'c', 'd']
- it produces:
- {
- 'sql_params_list': [
- ('INSERT INTO T (f1, f2) VALUES (%s, %s)', ('a', 'b')),
- ('INSERT INTO T (f1, f2) VALUES (%s, %s)', ('c', 'd'))
- ],
- }
-
- Case d)
- SQL: INSERT INTO T (f1, f2) VALUES (%s, LOWER(%s)), (UPPER(%s), %s)
- Params: ['a', 'b', 'c', 'd']
- it produces:
- {
- 'sql_params_list': [
- ('INSERT INTO T (f1, f2) VALUES (%s, LOWER(%s))', ('a', 'b',)),
- ('INSERT INTO T (f1, f2) VALUES (UPPER(%s), %s)', ('c', 'd',))
- ],
- }
-
- :type insert_sql: str
- :param insert_sql: A SQL insert request.
-
- :type params: list
- :param params: A list of parameters.
-
- :rtype: dict
- :returns: A dictionary that maps `sql_params_list` to the list of
- parameters in cases a), b), d) or the dictionary with information
- about the resulting table in case c).
- """ # noqa
- match = RE_INSERT.search(insert_sql)
-
- if not match:
- raise ProgrammingError(
- "Could not parse an INSERT statement from %s" % insert_sql
- )
-
- after_values_sql = RE_VALUES_TILL_END.findall(insert_sql)
- if not after_values_sql:
- # Case b)
- insert_sql = sanitize_literals_for_upload(insert_sql)
- return {"sql_params_list": [(insert_sql, params)]}
-
- if not params:
- # Case a) perhaps?
- # Check if any %s exists.
-
- # pyformat_str_count = after_values_sql.count("%s")
- # if pyformat_str_count > 0:
- # raise ProgrammingError(
- # 'no params yet there are %d "%%s" tokens' % pyformat_str_count
- # )
- for item in after_values_sql:
- if item.count("%s") > 0:
- raise ProgrammingError(
- 'no params yet there are %d "%%s" tokens' % item.count("%s")
- )
-
- insert_sql = sanitize_literals_for_upload(insert_sql)
- # Confirmed case of:
- # SQL: INSERT INTO T (a1, a2) VALUES (1, 2)
- # Params: None
- return {"sql_params_list": [(insert_sql, None)]}
-
- _, values = expect(after_values_sql[0], VALUES)
-
- if values.homogenous():
- # Case c)
-
- columns = [mi.strip(" `") for mi in match.group("columns").split(",")]
- sql_params_list = []
- insert_sql_preamble = "INSERT INTO %s (%s) VALUES %s" % (
- match.group("table_name"),
- match.group("columns"),
- values.argv[0],
- )
- values_pyformat = [str(arg) for arg in values.argv]
- rows_list = rows_for_insert_or_update(columns, params, values_pyformat)
- insert_sql_preamble = sanitize_literals_for_upload(insert_sql_preamble)
- for row in rows_list:
- sql_params_list.append((insert_sql_preamble, row))
-
- return {"sql_params_list": sql_params_list}
-
- # Case d)
- # insert_sql is of the form:
- # INSERT INTO T(c1, c2) VALUES (%s, %s), (%s, LOWER(%s))
-
- # Sanity check:
- # length(all_args) == len(params)
- args_len = reduce(lambda a, b: a + b, [len(arg) for arg in values.argv])
- if args_len != len(params):
- raise ProgrammingError(
- "Invalid length: VALUES(...) len: %d != len(params): %d"
- % (args_len, len(params))
- )
-
- trim_index = insert_sql.find(after_values_sql[0])
- before_values_sql = insert_sql[:trim_index]
-
- sql_param_tuples = []
- for token_arg in values.argv:
- row_sql = before_values_sql + " VALUES%s" % token_arg
- row_sql = sanitize_literals_for_upload(row_sql)
- row_params, params = (
- tuple(params[0 : len(token_arg)]),
- params[len(token_arg) :],
- )
- sql_param_tuples.append((row_sql, row_params))
-
- return {"sql_params_list": sql_param_tuples}
-
-
-def rows_for_insert_or_update(columns, params, pyformat_args=None):
- """
- Create a tupled list of params to be used as a single value per
- value that inserted from a statement such as
- SQL: 'INSERT INTO t (f1, f2, f3) VALUES (%s, %s, %s), (%s, %s, %s), (%s, %s, %s)'
- Params A: [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
- Params B: [1, 2, 3, 4, 5, 6, 7, 8, 9]
-
- We'll have to convert both params types into:
- Params: [(1, 2, 3,), (4, 5, 6,), (7, 8, 9,)]
-
- :type columns: list
- :param columns: A list of the columns of the table.
-
- :type params: list
- :param params: A list of parameters.
-
- :rtype: list
- :returns: A properly restructured list of the parameters.
- """ # noqa
- if not pyformat_args:
- # This is the case where we have for example:
- # SQL: 'INSERT INTO t (f1, f2, f3)'
- # Params A: [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
- # Params B: [1, 2, 3, 4, 5, 6, 7, 8, 9]
- #
- # We'll have to convert both params types into:
- # [(1, 2, 3,), (4, 5, 6,), (7, 8, 9,)]
- contains_all_list_or_tuples = True
- for param in params:
- if not (isinstance(param, list) or isinstance(param, tuple)):
- contains_all_list_or_tuples = False
- break
-
- if contains_all_list_or_tuples:
- # The case with Params A: [(1, 2, 3), (4, 5, 6)]
- # Ensure that each param's length == len(columns)
- columns_len = len(columns)
- for param in params:
- if columns_len != len(param):
- raise Error(
- "\nlen(`%s`)=%d\n!=\ncolum_len(`%s`)=%d"
- % (param, len(param), columns, columns_len)
- )
- return params
- else:
- # The case with Params B: [1, 2, 3]
- # Insert statements' params are only passed as tuples or lists,
- # yet for do_execute_update, we've got to pass in list of list.
- # https://googleapis.dev/python/spanner/latest/transaction-api.html\
- # #google.cloud.spanner_v1.transaction.Transaction.insert
- n_stride = len(columns)
- else:
- # This is the case where we have for example:
- # SQL: 'INSERT INTO t (f1, f2, f3) VALUES (%s, %s, %s),
- # (%s, %s, %s), (%s, %s, %s)'
- # Params: [1, 2, 3, 4, 5, 6, 7, 8, 9]
- # which should become
- # Columns: (f1, f2, f3)
- # new_params: [(1, 2, 3,), (4, 5, 6,), (7, 8, 9,)]
-
- # Sanity check 1: all the pyformat_values should have the exact same
- # length.
- first, rest = pyformat_args[0], pyformat_args[1:]
- n_stride = first.count("%s")
- for pyfmt_value in rest:
- n = pyfmt_value.count("%s")
- if n_stride != n:
- raise Error(
- "\nlen(`%s`)=%d\n!=\nlen(`%s`)=%d"
- % (first, n_stride, pyfmt_value, n)
- )
-
- # Sanity check 2: len(params) MUST be a multiple of n_stride aka
- # len(count of %s).
- # so that we can properly group for example:
- # Given pyformat args:
- # (%s, %s, %s)
- # Params:
- # [1, 2, 3, 4, 5, 6, 7, 8, 9]
- # into
- # [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
- if (len(params) % n_stride) != 0:
- raise ProgrammingError(
- "Invalid length: len(params)=%d MUST be a multiple of "
- "len(pyformat_args)=%d" % (len(params), n_stride)
- )
-
- # Now chop up the strides.
- strides = []
- for step in range(0, len(params), n_stride):
- stride = tuple(params[step : step + n_stride :])
- strides.append(stride)
-
- return strides
-
-
def sql_pyformat_args_to_spanner(sql, params):
"""
Transform pyformat set SQL to named arguments for Cloud Spanner.
diff --git a/google/cloud/spanner_v1/services/spanner/async_client.py b/google/cloud/spanner_v1/services/spanner/async_client.py
index e831c1c9b4..7721e7610d 100644
--- a/google/cloud/spanner_v1/services/spanner/async_client.py
+++ b/google/cloud/spanner_v1/services/spanner/async_client.py
@@ -249,9 +249,9 @@ async def create_session(
from google.cloud import spanner_v1
- def sample_create_session():
+ async def sample_create_session():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.CreateSessionRequest(
@@ -259,7 +259,7 @@ def sample_create_session():
)
# Make the request
- response = client.create_session(request=request)
+ response = await client.create_session(request=request)
# Handle the response
print(response)
@@ -355,9 +355,9 @@ async def batch_create_sessions(
from google.cloud import spanner_v1
- def sample_batch_create_sessions():
+ async def sample_batch_create_sessions():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.BatchCreateSessionsRequest(
@@ -366,7 +366,7 @@ def sample_batch_create_sessions():
)
# Make the request
- response = client.batch_create_sessions(request=request)
+ response = await client.batch_create_sessions(request=request)
# Handle the response
print(response)
@@ -476,9 +476,9 @@ async def get_session(
from google.cloud import spanner_v1
- def sample_get_session():
+ async def sample_get_session():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.GetSessionRequest(
@@ -486,7 +486,7 @@ def sample_get_session():
)
# Make the request
- response = client.get_session(request=request)
+ response = await client.get_session(request=request)
# Handle the response
print(response)
@@ -578,9 +578,9 @@ async def list_sessions(
from google.cloud import spanner_v1
- def sample_list_sessions():
+ async def sample_list_sessions():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.ListSessionsRequest(
@@ -591,7 +591,7 @@ def sample_list_sessions():
page_result = client.list_sessions(request=request)
# Handle the response
- for response in page_result:
+ async for response in page_result:
print(response)
Args:
@@ -697,9 +697,9 @@ async def delete_session(
from google.cloud import spanner_v1
- def sample_delete_session():
+ async def sample_delete_session():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.DeleteSessionRequest(
@@ -707,7 +707,7 @@ def sample_delete_session():
)
# Make the request
- client.delete_session(request=request)
+ await client.delete_session(request=request)
Args:
request (Union[google.cloud.spanner_v1.types.DeleteSessionRequest, dict]):
@@ -801,9 +801,9 @@ async def execute_sql(
from google.cloud import spanner_v1
- def sample_execute_sql():
+ async def sample_execute_sql():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.ExecuteSqlRequest(
@@ -812,7 +812,7 @@ def sample_execute_sql():
)
# Make the request
- response = client.execute_sql(request=request)
+ response = await client.execute_sql(request=request)
# Handle the response
print(response)
@@ -890,9 +890,9 @@ def execute_streaming_sql(
from google.cloud import spanner_v1
- def sample_execute_streaming_sql():
+ async def sample_execute_streaming_sql():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.ExecuteSqlRequest(
@@ -901,10 +901,10 @@ def sample_execute_streaming_sql():
)
# Make the request
- stream = client.execute_streaming_sql(request=request)
+ stream = await client.execute_streaming_sql(request=request)
# Handle the response
- for response in stream:
+ async for response in stream:
print(response)
Args:
@@ -982,9 +982,9 @@ async def execute_batch_dml(
from google.cloud import spanner_v1
- def sample_execute_batch_dml():
+ async def sample_execute_batch_dml():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
statements = spanner_v1.Statement()
@@ -997,7 +997,7 @@ def sample_execute_batch_dml():
)
# Make the request
- response = client.execute_batch_dml(request=request)
+ response = await client.execute_batch_dml(request=request)
# Handle the response
print(response)
@@ -1120,9 +1120,9 @@ async def read(
from google.cloud import spanner_v1
- def sample_read():
+ async def sample_read():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.ReadRequest(
@@ -1132,7 +1132,7 @@ def sample_read():
)
# Make the request
- response = client.read(request=request)
+ response = await client.read(request=request)
# Handle the response
print(response)
@@ -1210,9 +1210,9 @@ def streaming_read(
from google.cloud import spanner_v1
- def sample_streaming_read():
+ async def sample_streaming_read():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.ReadRequest(
@@ -1222,10 +1222,10 @@ def sample_streaming_read():
)
# Make the request
- stream = client.streaming_read(request=request)
+ stream = await client.streaming_read(request=request)
# Handle the response
- for response in stream:
+ async for response in stream:
print(response)
Args:
@@ -1296,9 +1296,9 @@ async def begin_transaction(
from google.cloud import spanner_v1
- def sample_begin_transaction():
+ async def sample_begin_transaction():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.BeginTransactionRequest(
@@ -1306,7 +1306,7 @@ def sample_begin_transaction():
)
# Make the request
- response = client.begin_transaction(request=request)
+ response = await client.begin_transaction(request=request)
# Handle the response
print(response)
@@ -1425,9 +1425,9 @@ async def commit(
from google.cloud import spanner_v1
- def sample_commit():
+ async def sample_commit():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.CommitRequest(
@@ -1436,7 +1436,7 @@ def sample_commit():
)
# Make the request
- response = client.commit(request=request)
+ response = await client.commit(request=request)
# Handle the response
print(response)
@@ -1579,9 +1579,9 @@ async def rollback(
from google.cloud import spanner_v1
- def sample_rollback():
+ async def sample_rollback():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.RollbackRequest(
@@ -1590,7 +1590,7 @@ def sample_rollback():
)
# Make the request
- client.rollback(request=request)
+ await client.rollback(request=request)
Args:
request (Union[google.cloud.spanner_v1.types.RollbackRequest, dict]):
@@ -1693,9 +1693,9 @@ async def partition_query(
from google.cloud import spanner_v1
- def sample_partition_query():
+ async def sample_partition_query():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.PartitionQueryRequest(
@@ -1704,7 +1704,7 @@ def sample_partition_query():
)
# Make the request
- response = client.partition_query(request=request)
+ response = await client.partition_query(request=request)
# Handle the response
print(response)
@@ -1793,9 +1793,9 @@ async def partition_read(
from google.cloud import spanner_v1
- def sample_partition_read():
+ async def sample_partition_read():
# Create a client
- client = spanner_v1.SpannerClient()
+ client = spanner_v1.SpannerAsyncClient()
# Initialize request argument(s)
request = spanner_v1.PartitionReadRequest(
@@ -1804,7 +1804,7 @@ def sample_partition_read():
)
# Make the request
- response = client.partition_read(request=request)
+ response = await client.partition_read(request=request)
# Handle the response
print(response)
diff --git a/noxfile.py b/noxfile.py
index efe3b70104..57a4a1d179 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -25,7 +25,8 @@
import nox
BLACK_VERSION = "black==22.3.0"
-BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"]
+ISORT_VERSION = "isort==5.10.1"
+LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"]
DEFAULT_PYTHON_VERSION = "3.8"
@@ -85,7 +86,7 @@ def lint(session):
session.run(
"black",
"--check",
- *BLACK_PATHS,
+ *LINT_PATHS,
)
session.run("flake8", "google", "tests")
@@ -96,7 +97,27 @@ def blacken(session):
session.install(BLACK_VERSION)
session.run(
"black",
- *BLACK_PATHS,
+ *LINT_PATHS,
+ )
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def format(session):
+ """
+ Run isort to sort imports. Then run black
+ to format code to uniform standard.
+ """
+ session.install(BLACK_VERSION, ISORT_VERSION)
+ # Use the --fss option to sort imports using strict alphabetical order.
+ # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections
+ session.run(
+ "isort",
+ "--fss",
+ *LINT_PATHS,
+ )
+ session.run(
+ "black",
+ *LINT_PATHS,
)
diff --git a/samples/samples/noxfile.py b/samples/samples/noxfile.py
index 949e0fde9a..38bb0a572b 100644
--- a/samples/samples/noxfile.py
+++ b/samples/samples/noxfile.py
@@ -30,6 +30,7 @@
# WARNING - WARNING - WARNING - WARNING - WARNING
BLACK_VERSION = "black==22.3.0"
+ISORT_VERSION = "isort==5.10.1"
# Copy `noxfile_config.py` to your directory and modify it instead.
@@ -168,12 +169,32 @@ def lint(session: nox.sessions.Session) -> None:
@nox.session
def blacken(session: nox.sessions.Session) -> None:
+ """Run black. Format code to uniform standard."""
session.install(BLACK_VERSION)
python_files = [path for path in os.listdir(".") if path.endswith(".py")]
session.run("black", *python_files)
+#
+# format = isort + black
+#
+
+@nox.session
+def format(session: nox.sessions.Session) -> None:
+ """
+ Run isort to sort imports. Then run black
+ to format code to uniform standard.
+ """
+ session.install(BLACK_VERSION, ISORT_VERSION)
+ python_files = [path for path in os.listdir(".") if path.endswith(".py")]
+
+ # Use the --fss option to sort imports using strict alphabetical order.
+ # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections
+ session.run("isort", "--fss", *python_files)
+ session.run("black", *python_files)
+
+
#
# Sample Tests
#
diff --git a/samples/samples/requirements-test.txt b/samples/samples/requirements-test.txt
index 3d42f3a24a..dcaba12c6d 100644
--- a/samples/samples/requirements-test.txt
+++ b/samples/samples/requirements-test.txt
@@ -1,4 +1,4 @@
-pytest==7.1.1
+pytest==7.1.2
pytest-dependency==0.5.1
mock==4.0.3
google-cloud-testutils==1.3.1
diff --git a/samples/samples/requirements.txt b/samples/samples/requirements.txt
index c2b585853e..3ecc9eb46d 100644
--- a/samples/samples/requirements.txt
+++ b/samples/samples/requirements.txt
@@ -1,2 +1,2 @@
-google-cloud-spanner==3.13.0
+google-cloud-spanner==3.14.0
futures==3.3.0; python_version < "3"
diff --git a/scripts/readme-gen/readme_gen.py b/scripts/readme-gen/readme_gen.py
index d309d6e975..91b59676bf 100644
--- a/scripts/readme-gen/readme_gen.py
+++ b/scripts/readme-gen/readme_gen.py
@@ -28,7 +28,10 @@
jinja_env = jinja2.Environment(
trim_blocks=True,
loader=jinja2.FileSystemLoader(
- os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates'))))
+ os.path.abspath(os.path.join(os.path.dirname(__file__), "templates"))
+ ),
+ autoescape=True,
+)
README_TMPL = jinja_env.get_template('README.tmpl.rst')
diff --git a/setup.py b/setup.py
index 28fd020ab5..69489023ce 100644
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@
name = "google-cloud-spanner"
description = "Cloud Spanner API client library"
-version = "3.14.0"
+version = "3.14.1"
# Should be one of:
# 'Development Status :: 3 - Alpha'
# 'Development Status :: 4 - Beta'
@@ -38,9 +38,10 @@
# https://github.com/googleapis/google-cloud-python/issues/10566
"google-cloud-core >= 1.4.1, < 3.0dev",
"grpc-google-iam-v1 >= 0.12.4, <1.0.0dev",
- "proto-plus >= 1.15.0, != 1.19.6",
+ "proto-plus >= 1.15.0, <2.0.0dev, != 1.19.6",
"sqlparse >= 0.3.0",
"packaging >= 14.3",
+ "protobuf >= 3.19.0, <4.0.0dev",
]
extras = {
"tracing": [
diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt
index 4c581a9373..81c7b183a9 100644
--- a/testing/constraints-3.6.txt
+++ b/testing/constraints-3.6.txt
@@ -15,3 +15,4 @@ opentelemetry-api==1.1.0
opentelemetry-sdk==1.1.0
opentelemetry-instrumentation==0.20b0
packaging==14.3
+protobuf==3.19.0
diff --git a/testing/constraints-3.7.txt b/testing/constraints-3.7.txt
index e69de29bb2..81c7b183a9 100644
--- a/testing/constraints-3.7.txt
+++ b/testing/constraints-3.7.txt
@@ -0,0 +1,18 @@
+# This constraints file is used to check that lower bounds
+# are correct in setup.py
+# List *all* library dependencies and extras in this file.
+# Pin the version to the lower bound.
+#
+# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev",
+# Then this file should have foo==1.14.0
+google-api-core==1.31.5
+google-cloud-core==1.4.1
+grpc-google-iam-v1==0.12.4
+libcst==0.2.5
+proto-plus==1.15.0
+sqlparse==0.3.0
+opentelemetry-api==1.1.0
+opentelemetry-sdk==1.1.0
+opentelemetry-instrumentation==0.20b0
+packaging==14.3
+protobuf==3.19.0
diff --git a/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py b/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py
index bf1a442f66..de001b2663 100644
--- a/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py
+++ b/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py
@@ -14,7 +14,13 @@
# limitations under the License.
#
import os
-import mock
+
+# try/except added for compatibility with python < 3.8
+try:
+ from unittest import mock
+ from unittest.mock import AsyncMock
+except ImportError:
+ import mock
import grpc
from grpc.experimental import aio
@@ -768,7 +774,7 @@ def test_list_databases_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.ListDatabasesRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_databases), "__call__") as call:
@@ -784,7 +790,7 @@ def test_list_databases_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -798,7 +804,7 @@ async def test_list_databases_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.ListDatabasesRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_databases), "__call__") as call:
@@ -816,7 +822,7 @@ async def test_list_databases_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -947,7 +953,7 @@ def test_list_databases_pager(transport_name: str = "grpc"):
assert pager._metadata == metadata
- results = [i for i in pager]
+ results = list(pager)
assert len(results) == 6
assert all(isinstance(i, spanner_database_admin.Database) for i in results)
@@ -1183,7 +1189,7 @@ def test_create_database_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.CreateDatabaseRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_database), "__call__") as call:
@@ -1199,7 +1205,7 @@ def test_create_database_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -1213,7 +1219,7 @@ async def test_create_database_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.CreateDatabaseRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_database), "__call__") as call:
@@ -1231,7 +1237,7 @@ async def test_create_database_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -1442,7 +1448,7 @@ def test_get_database_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.GetDatabaseRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_database), "__call__") as call:
@@ -1458,7 +1464,7 @@ def test_get_database_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1472,7 +1478,7 @@ async def test_get_database_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.GetDatabaseRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_database), "__call__") as call:
@@ -1490,7 +1496,7 @@ async def test_get_database_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1675,7 +1681,7 @@ def test_update_database_ddl_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.UpdateDatabaseDdlRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -1693,7 +1699,7 @@ def test_update_database_ddl_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -1707,7 +1713,7 @@ async def test_update_database_ddl_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.UpdateDatabaseDdlRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -1727,7 +1733,7 @@ async def test_update_database_ddl_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -1918,7 +1924,7 @@ def test_drop_database_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.DropDatabaseRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.drop_database), "__call__") as call:
@@ -1934,7 +1940,7 @@ def test_drop_database_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -1948,7 +1954,7 @@ async def test_drop_database_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.DropDatabaseRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.drop_database), "__call__") as call:
@@ -1964,7 +1970,7 @@ async def test_drop_database_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -2147,7 +2153,7 @@ def test_get_database_ddl_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.GetDatabaseDdlRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_database_ddl), "__call__") as call:
@@ -2163,7 +2169,7 @@ def test_get_database_ddl_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -2177,7 +2183,7 @@ async def test_get_database_ddl_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.GetDatabaseDdlRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_database_ddl), "__call__") as call:
@@ -2195,7 +2201,7 @@ async def test_get_database_ddl_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -2383,7 +2389,7 @@ def test_set_iam_policy_field_headers():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.SetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.set_iam_policy), "__call__") as call:
@@ -2399,7 +2405,7 @@ def test_set_iam_policy_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -2413,7 +2419,7 @@ async def test_set_iam_policy_field_headers_async():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.SetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.set_iam_policy), "__call__") as call:
@@ -2429,7 +2435,7 @@ async def test_set_iam_policy_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -2633,7 +2639,7 @@ def test_get_iam_policy_field_headers():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.GetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_iam_policy), "__call__") as call:
@@ -2649,7 +2655,7 @@ def test_get_iam_policy_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -2663,7 +2669,7 @@ async def test_get_iam_policy_field_headers_async():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.GetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_iam_policy), "__call__") as call:
@@ -2679,7 +2685,7 @@ async def test_get_iam_policy_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -2885,7 +2891,7 @@ def test_test_iam_permissions_field_headers():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.TestIamPermissionsRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2903,7 +2909,7 @@ def test_test_iam_permissions_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -2917,7 +2923,7 @@ async def test_test_iam_permissions_field_headers_async():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.TestIamPermissionsRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2937,7 +2943,7 @@ async def test_test_iam_permissions_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -3148,7 +3154,7 @@ def test_create_backup_field_headers():
# a field header. Set these to a non-empty value.
request = gsad_backup.CreateBackupRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_backup), "__call__") as call:
@@ -3164,7 +3170,7 @@ def test_create_backup_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -3178,7 +3184,7 @@ async def test_create_backup_field_headers_async():
# a field header. Set these to a non-empty value.
request = gsad_backup.CreateBackupRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_backup), "__call__") as call:
@@ -3196,7 +3202,7 @@ async def test_create_backup_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -3394,7 +3400,7 @@ def test_copy_backup_field_headers():
# a field header. Set these to a non-empty value.
request = backup.CopyBackupRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.copy_backup), "__call__") as call:
@@ -3410,7 +3416,7 @@ def test_copy_backup_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -3424,7 +3430,7 @@ async def test_copy_backup_field_headers_async():
# a field header. Set these to a non-empty value.
request = backup.CopyBackupRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.copy_backup), "__call__") as call:
@@ -3442,7 +3448,7 @@ async def test_copy_backup_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -3680,7 +3686,7 @@ def test_get_backup_field_headers():
# a field header. Set these to a non-empty value.
request = backup.GetBackupRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_backup), "__call__") as call:
@@ -3696,7 +3702,7 @@ def test_get_backup_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -3710,7 +3716,7 @@ async def test_get_backup_field_headers_async():
# a field header. Set these to a non-empty value.
request = backup.GetBackupRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_backup), "__call__") as call:
@@ -3726,7 +3732,7 @@ async def test_get_backup_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -3932,7 +3938,7 @@ def test_update_backup_field_headers():
# a field header. Set these to a non-empty value.
request = gsad_backup.UpdateBackupRequest()
- request.backup.name = "backup.name/value"
+ request.backup.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.update_backup), "__call__") as call:
@@ -3948,7 +3954,7 @@ def test_update_backup_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "backup.name=backup.name/value",
+ "backup.name=name_value",
) in kw["metadata"]
@@ -3962,7 +3968,7 @@ async def test_update_backup_field_headers_async():
# a field header. Set these to a non-empty value.
request = gsad_backup.UpdateBackupRequest()
- request.backup.name = "backup.name/value"
+ request.backup.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.update_backup), "__call__") as call:
@@ -3978,7 +3984,7 @@ async def test_update_backup_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "backup.name=backup.name/value",
+ "backup.name=name_value",
) in kw["metadata"]
@@ -4162,7 +4168,7 @@ def test_delete_backup_field_headers():
# a field header. Set these to a non-empty value.
request = backup.DeleteBackupRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.delete_backup), "__call__") as call:
@@ -4178,7 +4184,7 @@ def test_delete_backup_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -4192,7 +4198,7 @@ async def test_delete_backup_field_headers_async():
# a field header. Set these to a non-empty value.
request = backup.DeleteBackupRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.delete_backup), "__call__") as call:
@@ -4208,7 +4214,7 @@ async def test_delete_backup_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -4390,7 +4396,7 @@ def test_list_backups_field_headers():
# a field header. Set these to a non-empty value.
request = backup.ListBackupsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_backups), "__call__") as call:
@@ -4406,7 +4412,7 @@ def test_list_backups_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -4420,7 +4426,7 @@ async def test_list_backups_field_headers_async():
# a field header. Set these to a non-empty value.
request = backup.ListBackupsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_backups), "__call__") as call:
@@ -4438,7 +4444,7 @@ async def test_list_backups_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -4569,7 +4575,7 @@ def test_list_backups_pager(transport_name: str = "grpc"):
assert pager._metadata == metadata
- results = [i for i in pager]
+ results = list(pager)
assert len(results) == 6
assert all(isinstance(i, backup.Backup) for i in results)
@@ -4805,7 +4811,7 @@ def test_restore_database_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.RestoreDatabaseRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.restore_database), "__call__") as call:
@@ -4821,7 +4827,7 @@ def test_restore_database_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -4835,7 +4841,7 @@ async def test_restore_database_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.RestoreDatabaseRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.restore_database), "__call__") as call:
@@ -4853,7 +4859,7 @@ async def test_restore_database_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -5060,7 +5066,7 @@ def test_list_database_operations_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.ListDatabaseOperationsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -5078,7 +5084,7 @@ def test_list_database_operations_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -5092,7 +5098,7 @@ async def test_list_database_operations_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_database_admin.ListDatabaseOperationsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -5112,7 +5118,7 @@ async def test_list_database_operations_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -5249,7 +5255,7 @@ def test_list_database_operations_pager(transport_name: str = "grpc"):
assert pager._metadata == metadata
- results = [i for i in pager]
+ results = list(pager)
assert len(results) == 6
assert all(isinstance(i, operations_pb2.Operation) for i in results)
@@ -5502,7 +5508,7 @@ def test_list_backup_operations_field_headers():
# a field header. Set these to a non-empty value.
request = backup.ListBackupOperationsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -5520,7 +5526,7 @@ def test_list_backup_operations_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -5534,7 +5540,7 @@ async def test_list_backup_operations_field_headers_async():
# a field header. Set these to a non-empty value.
request = backup.ListBackupOperationsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -5554,7 +5560,7 @@ async def test_list_backup_operations_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -5691,7 +5697,7 @@ def test_list_backup_operations_pager(transport_name: str = "grpc"):
assert pager._metadata == metadata
- results = [i for i in pager]
+ results = list(pager)
assert len(results) == 6
assert all(isinstance(i, operations_pb2.Operation) for i in results)
diff --git a/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py b/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py
index 59e7134f41..7d96090b8f 100644
--- a/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py
+++ b/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py
@@ -14,7 +14,13 @@
# limitations under the License.
#
import os
-import mock
+
+# try/except added for compatibility with python < 3.8
+try:
+ from unittest import mock
+ from unittest.mock import AsyncMock
+except ImportError:
+ import mock
import grpc
from grpc.experimental import aio
@@ -767,7 +773,7 @@ def test_list_instance_configs_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.ListInstanceConfigsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -785,7 +791,7 @@ def test_list_instance_configs_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -799,7 +805,7 @@ async def test_list_instance_configs_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.ListInstanceConfigsRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -819,7 +825,7 @@ async def test_list_instance_configs_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -956,7 +962,7 @@ def test_list_instance_configs_pager(transport_name: str = "grpc"):
assert pager._metadata == metadata
- results = [i for i in pager]
+ results = list(pager)
assert len(results) == 6
assert all(
isinstance(i, spanner_instance_admin.InstanceConfig) for i in results
@@ -1222,7 +1228,7 @@ def test_get_instance_config_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.GetInstanceConfigRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -1240,7 +1246,7 @@ def test_get_instance_config_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1254,7 +1260,7 @@ async def test_get_instance_config_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.GetInstanceConfigRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -1274,7 +1280,7 @@ async def test_get_instance_config_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1463,7 +1469,7 @@ def test_list_instances_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.ListInstancesRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_instances), "__call__") as call:
@@ -1479,7 +1485,7 @@ def test_list_instances_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -1493,7 +1499,7 @@ async def test_list_instances_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.ListInstancesRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_instances), "__call__") as call:
@@ -1511,7 +1517,7 @@ async def test_list_instances_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -1642,7 +1648,7 @@ def test_list_instances_pager(transport_name: str = "grpc"):
assert pager._metadata == metadata
- results = [i for i in pager]
+ results = list(pager)
assert len(results) == 6
assert all(isinstance(i, spanner_instance_admin.Instance) for i in results)
@@ -1908,7 +1914,7 @@ def test_get_instance_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.GetInstanceRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_instance), "__call__") as call:
@@ -1924,7 +1930,7 @@ def test_get_instance_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1938,7 +1944,7 @@ async def test_get_instance_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.GetInstanceRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_instance), "__call__") as call:
@@ -1956,7 +1962,7 @@ async def test_get_instance_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -2135,7 +2141,7 @@ def test_create_instance_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.CreateInstanceRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_instance), "__call__") as call:
@@ -2151,7 +2157,7 @@ def test_create_instance_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -2165,7 +2171,7 @@ async def test_create_instance_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.CreateInstanceRequest()
- request.parent = "parent/value"
+ request.parent = "parent_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_instance), "__call__") as call:
@@ -2183,7 +2189,7 @@ async def test_create_instance_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "parent=parent/value",
+ "parent=parent_value",
) in kw["metadata"]
@@ -2382,7 +2388,7 @@ def test_update_instance_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.UpdateInstanceRequest()
- request.instance.name = "instance.name/value"
+ request.instance.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.update_instance), "__call__") as call:
@@ -2398,7 +2404,7 @@ def test_update_instance_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "instance.name=instance.name/value",
+ "instance.name=name_value",
) in kw["metadata"]
@@ -2412,7 +2418,7 @@ async def test_update_instance_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.UpdateInstanceRequest()
- request.instance.name = "instance.name/value"
+ request.instance.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.update_instance), "__call__") as call:
@@ -2430,7 +2436,7 @@ async def test_update_instance_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "instance.name=instance.name/value",
+ "instance.name=name_value",
) in kw["metadata"]
@@ -2617,7 +2623,7 @@ def test_delete_instance_field_headers():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.DeleteInstanceRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.delete_instance), "__call__") as call:
@@ -2633,7 +2639,7 @@ def test_delete_instance_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -2647,7 +2653,7 @@ async def test_delete_instance_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner_instance_admin.DeleteInstanceRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.delete_instance), "__call__") as call:
@@ -2663,7 +2669,7 @@ async def test_delete_instance_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -2849,7 +2855,7 @@ def test_set_iam_policy_field_headers():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.SetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.set_iam_policy), "__call__") as call:
@@ -2865,7 +2871,7 @@ def test_set_iam_policy_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -2879,7 +2885,7 @@ async def test_set_iam_policy_field_headers_async():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.SetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.set_iam_policy), "__call__") as call:
@@ -2895,7 +2901,7 @@ async def test_set_iam_policy_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -3099,7 +3105,7 @@ def test_get_iam_policy_field_headers():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.GetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_iam_policy), "__call__") as call:
@@ -3115,7 +3121,7 @@ def test_get_iam_policy_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -3129,7 +3135,7 @@ async def test_get_iam_policy_field_headers_async():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.GetIamPolicyRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_iam_policy), "__call__") as call:
@@ -3145,7 +3151,7 @@ async def test_get_iam_policy_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -3351,7 +3357,7 @@ def test_test_iam_permissions_field_headers():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.TestIamPermissionsRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -3369,7 +3375,7 @@ def test_test_iam_permissions_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
@@ -3383,7 +3389,7 @@ async def test_test_iam_permissions_field_headers_async():
# a field header. Set these to a non-empty value.
request = iam_policy_pb2.TestIamPermissionsRequest()
- request.resource = "resource/value"
+ request.resource = "resource_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -3403,7 +3409,7 @@ async def test_test_iam_permissions_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "resource=resource/value",
+ "resource=resource_value",
) in kw["metadata"]
diff --git a/tests/unit/gapic/spanner_v1/test_spanner.py b/tests/unit/gapic/spanner_v1/test_spanner.py
index d4df289e48..f2b1471240 100644
--- a/tests/unit/gapic/spanner_v1/test_spanner.py
+++ b/tests/unit/gapic/spanner_v1/test_spanner.py
@@ -14,7 +14,13 @@
# limitations under the License.
#
import os
-import mock
+
+# try/except added for compatibility with python < 3.8
+try:
+ from unittest import mock
+ from unittest.mock import AsyncMock
+except ImportError:
+ import mock
import grpc
from grpc.experimental import aio
@@ -712,7 +718,7 @@ def test_create_session_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.CreateSessionRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_session), "__call__") as call:
@@ -728,7 +734,7 @@ def test_create_session_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -742,7 +748,7 @@ async def test_create_session_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.CreateSessionRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.create_session), "__call__") as call:
@@ -758,7 +764,7 @@ async def test_create_session_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -940,7 +946,7 @@ def test_batch_create_sessions_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.BatchCreateSessionsRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -958,7 +964,7 @@ def test_batch_create_sessions_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -972,7 +978,7 @@ async def test_batch_create_sessions_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.BatchCreateSessionsRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -992,7 +998,7 @@ async def test_batch_create_sessions_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -1190,7 +1196,7 @@ def test_get_session_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.GetSessionRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_session), "__call__") as call:
@@ -1206,7 +1212,7 @@ def test_get_session_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1220,7 +1226,7 @@ async def test_get_session_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.GetSessionRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.get_session), "__call__") as call:
@@ -1236,7 +1242,7 @@ async def test_get_session_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1418,7 +1424,7 @@ def test_list_sessions_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.ListSessionsRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_sessions), "__call__") as call:
@@ -1434,7 +1440,7 @@ def test_list_sessions_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -1448,7 +1454,7 @@ async def test_list_sessions_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.ListSessionsRequest()
- request.database = "database/value"
+ request.database = "database_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.list_sessions), "__call__") as call:
@@ -1466,7 +1472,7 @@ async def test_list_sessions_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "database=database/value",
+ "database=database_value",
) in kw["metadata"]
@@ -1597,7 +1603,7 @@ def test_list_sessions_pager(transport_name: str = "grpc"):
assert pager._metadata == metadata
- results = [i for i in pager]
+ results = list(pager)
assert len(results) == 6
assert all(isinstance(i, spanner.Session) for i in results)
@@ -1830,7 +1836,7 @@ def test_delete_session_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.DeleteSessionRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.delete_session), "__call__") as call:
@@ -1846,7 +1852,7 @@ def test_delete_session_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -1860,7 +1866,7 @@ async def test_delete_session_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.DeleteSessionRequest()
- request.name = "name/value"
+ request.name = "name_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.delete_session), "__call__") as call:
@@ -1876,7 +1882,7 @@ async def test_delete_session_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "name=name/value",
+ "name=name_value",
) in kw["metadata"]
@@ -2052,7 +2058,7 @@ def test_execute_sql_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.ExecuteSqlRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.execute_sql), "__call__") as call:
@@ -2068,7 +2074,7 @@ def test_execute_sql_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2082,7 +2088,7 @@ async def test_execute_sql_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.ExecuteSqlRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.execute_sql), "__call__") as call:
@@ -2100,7 +2106,7 @@ async def test_execute_sql_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2205,7 +2211,7 @@ def test_execute_streaming_sql_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.ExecuteSqlRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2223,7 +2229,7 @@ def test_execute_streaming_sql_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2237,7 +2243,7 @@ async def test_execute_streaming_sql_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.ExecuteSqlRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2258,7 +2264,7 @@ async def test_execute_streaming_sql_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2360,7 +2366,7 @@ def test_execute_batch_dml_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.ExecuteBatchDmlRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2378,7 +2384,7 @@ def test_execute_batch_dml_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2392,7 +2398,7 @@ async def test_execute_batch_dml_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.ExecuteBatchDmlRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2412,7 +2418,7 @@ async def test_execute_batch_dml_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2508,7 +2514,7 @@ def test_read_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.ReadRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.read), "__call__") as call:
@@ -2524,7 +2530,7 @@ def test_read_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2538,7 +2544,7 @@ async def test_read_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.ReadRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.read), "__call__") as call:
@@ -2556,7 +2562,7 @@ async def test_read_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2655,7 +2661,7 @@ def test_streaming_read_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.ReadRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.streaming_read), "__call__") as call:
@@ -2671,7 +2677,7 @@ def test_streaming_read_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2685,7 +2691,7 @@ async def test_streaming_read_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.ReadRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.streaming_read), "__call__") as call:
@@ -2704,7 +2710,7 @@ async def test_streaming_read_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2812,7 +2818,7 @@ def test_begin_transaction_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.BeginTransactionRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2830,7 +2836,7 @@ def test_begin_transaction_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -2844,7 +2850,7 @@ async def test_begin_transaction_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.BeginTransactionRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
@@ -2864,7 +2870,7 @@ async def test_begin_transaction_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3056,7 +3062,7 @@ def test_commit_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.CommitRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.commit), "__call__") as call:
@@ -3072,7 +3078,7 @@ def test_commit_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3086,7 +3092,7 @@ async def test_commit_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.CommitRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.commit), "__call__") as call:
@@ -3104,7 +3110,7 @@ async def test_commit_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3316,7 +3322,7 @@ def test_rollback_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.RollbackRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.rollback), "__call__") as call:
@@ -3332,7 +3338,7 @@ def test_rollback_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3346,7 +3352,7 @@ async def test_rollback_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.RollbackRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.rollback), "__call__") as call:
@@ -3362,7 +3368,7 @@ async def test_rollback_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3548,7 +3554,7 @@ def test_partition_query_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.PartitionQueryRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.partition_query), "__call__") as call:
@@ -3564,7 +3570,7 @@ def test_partition_query_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3578,7 +3584,7 @@ async def test_partition_query_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.PartitionQueryRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.partition_query), "__call__") as call:
@@ -3596,7 +3602,7 @@ async def test_partition_query_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3692,7 +3698,7 @@ def test_partition_read_field_headers():
# a field header. Set these to a non-empty value.
request = spanner.PartitionReadRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.partition_read), "__call__") as call:
@@ -3708,7 +3714,7 @@ def test_partition_read_field_headers():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
@@ -3722,7 +3728,7 @@ async def test_partition_read_field_headers_async():
# a field header. Set these to a non-empty value.
request = spanner.PartitionReadRequest()
- request.session = "session/value"
+ request.session = "session_value"
# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(type(client.transport.partition_read), "__call__") as call:
@@ -3740,7 +3746,7 @@ async def test_partition_read_field_headers_async():
_, _, kw = call.mock_calls[0]
assert (
"x-goog-request-params",
- "session=session/value",
+ "session=session_value",
) in kw["metadata"]
diff --git a/tests/unit/spanner_dbapi/test__helpers.py b/tests/unit/spanner_dbapi/test__helpers.py
index 84d6b3e323..1782978d62 100644
--- a/tests/unit/spanner_dbapi/test__helpers.py
+++ b/tests/unit/spanner_dbapi/test__helpers.py
@@ -32,23 +32,37 @@ def test__execute_insert_heterogenous(self):
"google.cloud.spanner_dbapi._helpers.get_param_types", return_value=None
) as mock_param_types:
transaction = mock.MagicMock()
- transaction.execute_update = mock_execute = mock.MagicMock()
- _helpers._execute_insert_heterogenous(transaction, [params])
+ transaction.execute_update = mock_update = mock.MagicMock()
+ _helpers._execute_insert_heterogenous(transaction, (params,))
mock_pyformat.assert_called_once_with(params[0], params[1])
mock_param_types.assert_called_once_with(None)
- mock_execute.assert_called_once_with(sql, params=None, param_types=None)
+ mock_update.assert_called_once_with(sql, None, None)
- def test__execute_insert_homogenous(self):
+ def test__execute_insert_heterogenous_error(self):
from google.cloud.spanner_dbapi import _helpers
+ from google.api_core.exceptions import Unknown
- transaction = mock.MagicMock()
- transaction.insert = mock.MagicMock()
- parts = mock.MagicMock()
- parts.get = mock.MagicMock(return_value=0)
+ sql = "sql"
+ params = (sql, None)
+ with mock.patch(
+ "google.cloud.spanner_dbapi._helpers.sql_pyformat_args_to_spanner",
+ return_value=params,
+ ) as mock_pyformat:
+ with mock.patch(
+ "google.cloud.spanner_dbapi._helpers.get_param_types", return_value=None
+ ) as mock_param_types:
+ transaction = mock.MagicMock()
+ transaction.execute_update = mock_update = mock.MagicMock(
+ side_effect=Unknown("Unknown")
+ )
- _helpers._execute_insert_homogenous(transaction, parts)
- transaction.insert.assert_called_once_with(0, 0, 0)
+ with self.assertRaises(Unknown):
+ _helpers._execute_insert_heterogenous(transaction, (params,))
+
+ mock_pyformat.assert_called_once_with(params[0], params[1])
+ mock_param_types.assert_called_once_with(None)
+ mock_update.assert_called_once_with(sql, None, None)
def test_handle_insert(self):
from google.cloud.spanner_dbapi import _helpers
@@ -56,19 +70,13 @@ def test_handle_insert(self):
connection = mock.MagicMock()
connection.database.run_in_transaction = mock_run_in = mock.MagicMock()
sql = "sql"
- parts = mock.MagicMock()
- with mock.patch(
- "google.cloud.spanner_dbapi._helpers.parse_insert", return_value=parts
- ):
- parts.get = mock.MagicMock(return_value=True)
- mock_run_in.return_value = 0
- result = _helpers.handle_insert(connection, sql, None)
- self.assertEqual(result, 0)
-
- parts.get = mock.MagicMock(return_value=False)
- mock_run_in.return_value = 1
- result = _helpers.handle_insert(connection, sql, None)
- self.assertEqual(result, 1)
+ mock_run_in.return_value = 0
+ result = _helpers.handle_insert(connection, sql, None)
+ self.assertEqual(result, 0)
+
+ mock_run_in.return_value = 1
+ result = _helpers.handle_insert(connection, sql, None)
+ self.assertEqual(result, 1)
class TestColumnInfo(unittest.TestCase):
diff --git a/tests/unit/spanner_dbapi/test_connection.py b/tests/unit/spanner_dbapi/test_connection.py
index 7902de6405..e15f6af33b 100644
--- a/tests/unit/spanner_dbapi/test_connection.py
+++ b/tests/unit/spanner_dbapi/test_connection.py
@@ -392,13 +392,17 @@ def test_run_statement_w_heterogenous_insert_statements(self):
"""Check that Connection executed heterogenous insert statements."""
from google.cloud.spanner_dbapi.checksum import ResultsChecksum
from google.cloud.spanner_dbapi.cursor import Statement
+ from google.rpc.status_pb2 import Status
+ from google.rpc.code_pb2 import OK
sql = "INSERT INTO T (f1, f2) VALUES (1, 2)"
params = None
param_types = None
connection = self._make_connection()
- connection.transaction_checkout = mock.Mock()
+ transaction = mock.MagicMock()
+ connection.transaction_checkout = mock.Mock(return_value=transaction)
+ transaction.batch_update = mock.Mock(return_value=(Status(code=OK), 1))
statement = Statement(sql, params, param_types, ResultsChecksum(), True)
connection.run_statement(statement, retried=True)
@@ -409,13 +413,17 @@ def test_run_statement_w_homogeneous_insert_statements(self):
"""Check that Connection executed homogeneous insert statements."""
from google.cloud.spanner_dbapi.checksum import ResultsChecksum
from google.cloud.spanner_dbapi.cursor import Statement
+ from google.rpc.status_pb2 import Status
+ from google.rpc.code_pb2 import OK
sql = "INSERT INTO T (f1, f2) VALUES (%s, %s), (%s, %s)"
params = ["a", "b", "c", "d"]
param_types = {"f1": str, "f2": str}
connection = self._make_connection()
- connection.transaction_checkout = mock.Mock()
+ transaction = mock.MagicMock()
+ connection.transaction_checkout = mock.Mock(return_value=transaction)
+ transaction.batch_update = mock.Mock(return_value=(Status(code=OK), 1))
statement = Statement(sql, params, param_types, ResultsChecksum(), True)
connection.run_statement(statement, retried=True)
diff --git a/tests/unit/spanner_dbapi/test_cursor.py b/tests/unit/spanner_dbapi/test_cursor.py
index 71e4a96d6e..3f379f96ac 100644
--- a/tests/unit/spanner_dbapi/test_cursor.py
+++ b/tests/unit/spanner_dbapi/test_cursor.py
@@ -564,7 +564,7 @@ def test_executemany_insert_batch_aborted(self):
transaction1 = mock.Mock(committed=False, rolled_back=False)
transaction1.batch_update = mock.Mock(
- side_effect=[(mock.Mock(code=ABORTED, details=err_details), [])]
+ side_effect=[(mock.Mock(code=ABORTED, message=err_details), [])]
)
transaction2 = self._transaction_mock()
@@ -732,15 +732,6 @@ def test_setoutputsize(self):
with self.assertRaises(exceptions.InterfaceError):
cursor.setoutputsize(size=None)
- # def test_handle_insert(self):
- # pass
- #
- # def test_do_execute_insert_heterogenous(self):
- # pass
- #
- # def test_do_execute_insert_homogenous(self):
- # pass
-
def test_handle_dql(self):
from google.cloud.spanner_dbapi import utils
from google.cloud.spanner_dbapi.cursor import _UNSET_COUNT
diff --git a/tests/unit/spanner_dbapi/test_parse_utils.py b/tests/unit/spanner_dbapi/test_parse_utils.py
index b0f363299b..511ad838cf 100644
--- a/tests/unit/spanner_dbapi/test_parse_utils.py
+++ b/tests/unit/spanner_dbapi/test_parse_utils.py
@@ -61,199 +61,6 @@ def test_classify_stmt(self):
for query, want_class in cases:
self.assertEqual(classify_stmt(query), want_class)
- @unittest.skipIf(skip_condition, skip_message)
- def test_parse_insert(self):
- from google.cloud.spanner_dbapi.parse_utils import parse_insert
- from google.cloud.spanner_dbapi.exceptions import ProgrammingError
-
- with self.assertRaises(ProgrammingError):
- parse_insert("bad-sql", None)
-
- cases = [
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s)",
- [1, 2, 3, 4, 5, 6],
- {
- "sql_params_list": [
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s)",
- (1, 2, 3),
- ),
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s)",
- (4, 5, 6),
- ),
- ]
- },
- ),
- (
- "INSERT INTO django_migrations(app, name, applied) VALUES (%s, %s, %s)",
- [1, 2, 3, 4, 5, 6],
- {
- "sql_params_list": [
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s)",
- (1, 2, 3),
- ),
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s)",
- (4, 5, 6),
- ),
- ]
- },
- ),
- (
- "INSERT INTO sales.addresses (street, city, state, zip_code) "
- "SELECT street, city, state, zip_code FROM sales.customers"
- "ORDER BY first_name, last_name",
- None,
- {
- "sql_params_list": [
- (
- "INSERT INTO sales.addresses (street, city, state, zip_code) "
- "SELECT street, city, state, zip_code FROM sales.customers"
- "ORDER BY first_name, last_name",
- None,
- )
- ]
- },
- ),
- (
- "INSERT INTO ap (n, ct, cn) "
- "VALUES (%s, %s, %s), (%s, %s, %s), (%s, %s, %s),(%s, %s, %s)",
- (1, 2, 3, 4, 5, 6, 7, 8, 9),
- {
- "sql_params_list": [
- ("INSERT INTO ap (n, ct, cn) VALUES (%s, %s, %s)", (1, 2, 3)),
- ("INSERT INTO ap (n, ct, cn) VALUES (%s, %s, %s)", (4, 5, 6)),
- ("INSERT INTO ap (n, ct, cn) VALUES (%s, %s, %s)", (7, 8, 9)),
- ]
- },
- ),
- (
- "INSERT INTO `no` (`yes`) VALUES (%s)",
- (1, 4, 5),
- {
- "sql_params_list": [
- ("INSERT INTO `no` (`yes`) VALUES (%s)", (1,)),
- ("INSERT INTO `no` (`yes`) VALUES (%s)", (4,)),
- ("INSERT INTO `no` (`yes`) VALUES (%s)", (5,)),
- ]
- },
- ),
- (
- "INSERT INTO T (f1, f2) VALUES (1, 2)",
- None,
- {"sql_params_list": [("INSERT INTO T (f1, f2) VALUES (1, 2)", None)]},
- ),
- (
- "INSERT INTO `no` (`yes`, tiff) VALUES (%s, LOWER(%s)), (%s, %s), (%s, %s)",
- (1, "FOO", 5, 10, 11, 29),
- {
- "sql_params_list": [
- (
- "INSERT INTO `no` (`yes`, tiff) VALUES(%s, LOWER(%s))",
- (1, "FOO"),
- ),
- ("INSERT INTO `no` (`yes`, tiff) VALUES(%s, %s)", (5, 10)),
- ("INSERT INTO `no` (`yes`, tiff) VALUES(%s, %s)", (11, 29)),
- ]
- },
- ),
- ]
-
- sql = "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s)"
- with self.assertRaises(ProgrammingError):
- parse_insert(sql, None)
-
- for sql, params, want in cases:
- with self.subTest(sql=sql):
- got = parse_insert(sql, params)
- self.assertEqual(got, want, "Mismatch with parse_insert of `%s`" % sql)
-
- @unittest.skipIf(skip_condition, skip_message)
- def test_parse_insert_invalid(self):
- from google.cloud.spanner_dbapi import exceptions
- from google.cloud.spanner_dbapi.parse_utils import parse_insert
-
- cases = [
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s), (%s, %s, %s)",
- [1, 2, 3, 4, 5, 6, 7],
- "len\\(params\\)=7 MUST be a multiple of len\\(pyformat_args\\)=3",
- ),
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s), (%s, %s, LOWER(%s))",
- [1, 2, 3, 4, 5, 6, 7],
- "Invalid length: VALUES\\(...\\) len: 6 != len\\(params\\): 7",
- ),
- (
- "INSERT INTO django_migrations (app, name, applied) VALUES (%s, %s, %s), (%s, %s, LOWER(%s)))",
- [1, 2, 3, 4, 5, 6],
- "VALUES: expected `,` got \\) in \\)",
- ),
- ]
-
- for sql, params, wantException in cases:
- with self.subTest(sql=sql):
- self.assertRaisesRegex(
- exceptions.ProgrammingError,
- wantException,
- lambda: parse_insert(sql, params),
- )
-
- @unittest.skipIf(skip_condition, skip_message)
- def test_rows_for_insert_or_update(self):
- from google.cloud.spanner_dbapi.parse_utils import rows_for_insert_or_update
- from google.cloud.spanner_dbapi.exceptions import Error
-
- with self.assertRaises(Error):
- rows_for_insert_or_update([0], [[]])
-
- with self.assertRaises(Error):
- rows_for_insert_or_update([0], None, ["0", "%s"])
-
- cases = [
- (
- ["id", "app", "name"],
- [(5, "ap", "n"), (6, "bp", "m")],
- None,
- [(5, "ap", "n"), (6, "bp", "m")],
- ),
- (
- ["app", "name"],
- [("ap", "n"), ("bp", "m")],
- None,
- [("ap", "n"), ("bp", "m")],
- ),
- (
- ["app", "name", "fn"],
- ["ap", "n", "f1", "bp", "m", "f2", "cp", "o", "f3"],
- ["(%s, %s, %s)", "(%s, %s, %s)", "(%s, %s, %s)"],
- [("ap", "n", "f1"), ("bp", "m", "f2"), ("cp", "o", "f3")],
- ),
- (
- ["app", "name", "fn", "ln"],
- [
- ("ap", "n", (45, "nested"), "ll"),
- ("bp", "m", "f2", "mt"),
- ("fp", "cp", "o", "f3"),
- ],
- None,
- [
- ("ap", "n", (45, "nested"), "ll"),
- ("bp", "m", "f2", "mt"),
- ("fp", "cp", "o", "f3"),
- ],
- ),
- (["app", "name", "fn"], ["ap", "n", "f1"], None, [("ap", "n", "f1")]),
- ]
-
- for i, (columns, params, pyformat_args, want) in enumerate(cases):
- with self.subTest(i=i):
- got = rows_for_insert_or_update(columns, params, pyformat_args)
- self.assertEqual(got, want)
-
@unittest.skipIf(skip_condition, skip_message)
def test_sql_pyformat_args_to_spanner(self):
from google.cloud.spanner_dbapi.parse_utils import sql_pyformat_args_to_spanner
@@ -411,20 +218,3 @@ def test_escape_name(self):
with self.subTest(name=name):
got = escape_name(name)
self.assertEqual(got, want)
-
- def test_insert_from_select(self):
- """Check that INSERT from SELECT clause can be executed with arguments."""
- from google.cloud.spanner_dbapi.parse_utils import parse_insert
-
- SQL = """
-INSERT INTO tab_name (id, data)
-SELECT tab_name.id + %s AS anon_1, tab_name.data
-FROM tab_name
-WHERE tab_name.data IN (%s, %s)
-"""
- ARGS = [5, "data2", "data3"]
-
- self.assertEqual(
- parse_insert(SQL, ARGS),
- {"sql_params_list": [(SQL, ARGS)]},
- )