I have Python method to create a database in GCP’s Spanner which in I want to set the database dialect to PostgreSql:
from google.cloud import spanner
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin, DatabaseDialect
def create_database(instance_id, database_id, extra_statements=None, database_dialect=DatabaseDialect.POSTGRESQL.value):
"""Create a new database"""
if extra_statements is None:
extra_statements = []
spanner_client = spanner.Client()
database_admin_api = spanner_client.database_admin_api
request = spanner_database_admin.CreateDatabaseRequest(
parent=database_admin_api.instance_path(
spanner_client.project, instance_id
),
create_statement=f"CREATE DATABASE `{database_id}`",
extra_statements=extra_statements,
database_dialect=database_dialect,
)
operation = database_admin_api.create_database(request=request)
database = operation.result(OPERATION_TIMEOUT_SECONDS)
But no matter what value I set for database_dialect parameter, I always get this error:
Traceback (most recent call last): File
"/home/ghasem/dayrize-cloud/.venv/lib/python3.10/site-packages/google/api_core/grpc_helpers.py",
line 76, in error_remapped_callable
return callable_(*args, **kwargs) File "/home/ghasem/dayrize-cloud/.venv/lib/python3.10/site-packages/grpc/_channel.py",
line 1161, in call
return _end_unary_response_blocking(state, call, False, None) File
"/home/ghasem/dayrize-cloud/.venv/lib/python3.10/site-packages/grpc/_channel.py",
line 1004, in _end_unary_response_blocking
raise _InactiveRpcError(state) # pytype: disable=not-instantiable grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that
terminated with:
status = StatusCode.INVALID_ARGUMENT
details = "Invalid create statement. Database ids should be 2-30 characters long, contain only lowercase letters, numbers,
underscores or hyphens, start with a letter and cannot end with an
underscore or hyphen. Example of valid create statement: CREATE
DATABASE "my-database""
debug_error_string = "UNKNOWN:Error received from peer ipv4:142.250.145.95:443 {grpc_message:"Invalid create statement.
Database ids should be 2-30 characters long, contain only lowercase
letters, numbers, underscores or hyphens, start with a letter and
cannot end with an underscore or hyphen. Example of valid create
statement: CREATE DATABASE "my-database"", grpc_status:3,
created_time:"2024-04-11T15:00:12.70067553+00:00"}"The above exception was the direct cause of the following exception:
Traceback (most recent call last): File "", line 1, in
File
"/home/ghasem/dayrize-cloud/dayrize-backend/src/dayrize_backend/helper/spanner.py",
line 31, in create_database
operation = database_admin_api.create_database(request=request) File
"/home/ghasem/dayrize-cloud/.venv/lib/python3.10/site-packages/google/cloud/spanner_admin_database_v1/services/database_admin/client.py",
line 821, in create_database
response = rpc( File "/home/ghasem/dayrize-cloud/.venv/lib/python3.10/site-packages/google/api_core/gapic_v1/method.py",
line 131, in call
return wrapped_func(*args, **kwargs) File "/home/ghasem/dayrize-cloud/.venv/lib/python3.10/site-packages/google/api_core/timeout.py", line 120, in func_with_timeout
return func(*args, **kwargs) File "/home/ghasem/dayrize-cloud/.venv/lib/python3.10/site-packages/google/api_core/grpc_helpers.py",
line 78, in error_remapped_callable
raise exceptions.from_grpc_error(exc) from exc google.api_core.exceptions.InvalidArgument: 400 Invalid create
statement. Database ids should be 2-30 characters long, contain only
lowercase letters, numbers, underscores or hyphens, start with a
letter and cannot end with an underscore or hyphen. Example of valid
create statement: CREATE DATABASE "my-database" [links {
description: "The rules of Cloud Spanner database IDs." url:
"https://cloud.google.com/spanner/docs/data-definition-language#database-id-names"
} ]
These are the values I set for database_dialect based on the documentations:
database_dialect=DatabaseDialect.POSTGRESQL.value
database_dialect=DatabaseDialect.POSTGRESQL
database_dialect=2
I know the database name is fine as if I remove the database_dialect from the statement, it will create the database without any problem.
What am I missing here?
>Solution :
The problem is that you are using GoogleSQL style quoting for the database name. Change this to the following:
OLD: create_statement=f"CREATE DATABASE `{database_id}`"
NEW: create_statement=f"CREATE DATABASE \"{database_id}\"",
(Note the double quotes instead of backticks!)
GoogleSQL uses backticks (“) to quote identifiers. PostgreSQL uses double quotes ("").