如何捕获扳手事务错误

问题描述

我目前正在为我的本地开发开发扳手模拟器,最终将使用实际实例。我正在尝试运行一个错误sql 查询,希望为用户捕获并抛出错误消息。

当我使用云运行以下查询时,我看到 HTTPError

gcloud spanner databases execute-sql --project=local-gcp-project testdb --instance=Emulator --sql='SELECT SingerId,AlbumId,AlbumTitle FROM Albums'

(gcloud.spanner.databases.execute-sql) HTTPError 400: {"error":"Table not found: Albums [at 1:43]\nSELECT SingerId,AlbumTitle FROM Albums\n^","code":3,"message":"Table not found: Albums [at 1:43]\nSELECT SingerId,AlbumTitle FROM Albums\n^"}

当我使用 python 客户端库运行相同的查询时,我没有看到任何错误,我看到 inside try 总是被打印出来。

spanner_client = spanner.Client()
instance = spanner_client.instance("Emulator")
database = instance.database("testdb")

def execute_transaction(transaction):
   query = "SELECT SingerId,AlbumTitle FROM Albums"
   transaction.execute_sql(sql=query)
try:
  database.run_in_transaction(execute_transaction)
  print("inside try")
except GoogleAPICallError as e:
  print("inside e")

知道我可能遗漏了什么吗?

解决方法

execute_sql 返回一个 StreamedResultSet,它被懒惰地评估。在迭代结果之前,您不会看到错误。更改示例以将结果集读入列表:

from google.cloud import spanner_v1 as spanner
from google.api_core.exceptions import GoogleAPICallError

spanner_client = spanner.Client()
instance = spanner_client.instance("Emulator")
database = instance.database("testdb")

def execute_transaction(transaction):
    query = "SELECT SingerId,AlbumId,AlbumTitle FROM Albums"
    return list(transaction.execute_sql(sql=query))

try:
    database.run_in_transaction(execute_transaction)
    print("inside try")  # never gets here
except GoogleAPICallError as ex:
    print(ex)  # 400 Table not found: Albums...