#google-cloud-spanner #google-cloud-spanner-emulator
#google-облако-spanner #google-cloud-spanner-emulator
Вопрос:
В настоящее время я работаю над эмулятором spanner для своей локальной разработки и в конечном итоге буду использовать реальные экземпляры. Я пытаюсь запустить неверный SQL-запрос, ожидающий перехвата и выдачи сообщения об ошибке для пользователей.
Когда я запускаю приведенный ниже запрос с использованием cloud, я вижу 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, AlbumId, AlbumTitle FROM Albumsn^","code":3,"message":"Table not found: Albums [at 1:43]nSELECT SingerId, AlbumId, AlbumTitle FROM Albumsn^"}
Когда я использую клиентскую библиотеку python для выполнения одного и того же запроса, я не вижу никаких ошибок и вижу inside try
, что они всегда печатаются.
spanner_client = spanner.Client()
instance = spanner_client.instance("Emulator")
database = instance.database("testdb")
def execute_transaction(transaction):
query = "SELECT SingerId, AlbumId, 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")
Есть идеи, чего мне может не хватать?
Ответ №1:
execute_sql
возвращает a 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...
Комментарии:
1. Спасибо, это было полезно. У меня есть куча SQL-запросов, которые необходимо выполнить. Похоже, мне нужно повторить результат для каждого из них. Это сработает для меня, но мне интересно, есть ли в базе данных параметр, который я могу изменить, чтобы изменить это поведение.
2. Нет, клиентские библиотеки Spanner возвращают итератор по дизайну. Если вы хотите получить все результаты,
execute_transaction
просто оберните их в alist
, как в примере.