Skip to content

Commit cba65bc

Browse files
committed
feat(bigquery): add bigquery_federated_view_schema_alloydb sample to inspect AlloyDB table schema via federated query
Problem: The BigQuery documentation (https://cloud.google.com/bigquery/docs/alloydb-federated-queries) needs a standalone, tested Python code sample demonstrating how to inspect AlloyDB table schema via federated query (region tag `bigquery_federated_view_schema_alloydb`). Solution: - Add `federated_view_schema_alloydb(project_id: str, connection_id: str) -> None` in `bigquery/federated_queries/bigquery_federated_view_schema_alloydb.py` (Query information_schema.columns in an AlloyDB database from BigQuery using EXTERNAL_QUERY.) - Add unit tests (`bigquery/federated_queries/bigquery_federated_view_schema_alloydb_test.py`) covering both the success path and API error handling (`GoogleAPICallError`)
1 parent 186be98 commit cba65bc

5 files changed

Lines changed: 170 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START bigquery_federated_view_schema_alloydb]
16+
import sys
17+
18+
from google.api_core import exceptions
19+
from google.cloud import bigquery
20+
21+
22+
def federated_view_schema_alloydb(
23+
project_id: str,
24+
connection_id: str,
25+
) -> None:
26+
"""Views an AlloyDB table schema from BigQuery using EXTERNAL_QUERY.
27+
28+
Args:
29+
project_id: Google Cloud project ID (for example, 'example-project').
30+
connection_id: Fully qualified BigQuery AlloyDB connection ID
31+
(for example, 'example-project.us-central1.example-alloydb-conn').
32+
"""
33+
client = bigquery.Client(project=project_id)
34+
# Query AlloyDB information_schema.columns inside EXTERNAL_QUERY to inspect table column metadata.
35+
external_sql = (
36+
"SELECT column_name, data_type, is_nullable "
37+
"FROM information_schema.columns "
38+
"WHERE table_schema = 'public' AND table_name = 'orders' "
39+
"ORDER BY ordinal_position ASC"
40+
)
41+
query = f"""
42+
SELECT
43+
column_name,
44+
data_type,
45+
is_nullable
46+
FROM EXTERNAL_QUERY('{connection_id}', "{external_sql}")
47+
ORDER BY column_name ASC;
48+
"""
49+
50+
try:
51+
print(f"Inspecting AlloyDB table schema via connection: {connection_id}")
52+
query_job = client.query(query)
53+
rows = list(query_job.result())
54+
except exceptions.NotFound as err:
55+
print(
56+
f"error: AlloyDB connection '{connection_id}' not found in project "
57+
f"'{project_id}': {err.message}",
58+
file=sys.stderr,
59+
)
60+
return
61+
except exceptions.GoogleAPICallError as err:
62+
print(
63+
f"error: could not inspect AlloyDB table schema on connection "
64+
f"'{connection_id}' in project '{project_id}': {err.message}",
65+
file=sys.stderr,
66+
)
67+
return
68+
69+
print(f"Resource ID: {connection_id}")
70+
print(f"Columns Returned: {len(rows)}")
71+
print(f"Job ID: {query_job.job_id}")
72+
73+
74+
# [END bigquery_federated_view_schema_alloydb]
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from unittest import mock
16+
17+
import bigquery_federated_view_schema_alloydb
18+
from google.api_core import exceptions
19+
import pytest
20+
21+
22+
def test_federated_view_schema_alloydb_success(
23+
monkeypatch: pytest.MonkeyPatch,
24+
capsys: pytest.CaptureFixture[str],
25+
) -> None:
26+
mock_client = mock.MagicMock()
27+
mock_job = mock.MagicMock()
28+
mock_job.job_id = "example-job-123"
29+
mock_job.result.return_value = [mock.MagicMock(), mock.MagicMock()]
30+
mock_client.query.return_value = mock_job
31+
monkeypatch.setattr(
32+
bigquery_federated_view_schema_alloydb.bigquery,
33+
"Client",
34+
lambda project=None: mock_client,
35+
)
36+
37+
bigquery_federated_view_schema_alloydb.federated_view_schema_alloydb(
38+
project_id="example-project",
39+
connection_id="example-project.us-central1.example-alloydb-conn",
40+
)
41+
42+
captured = capsys.readouterr()
43+
assert (
44+
"Resource ID: example-project.us-central1.example-alloydb-conn" in captured.out
45+
)
46+
assert "Columns Returned: 2" in captured.out
47+
assert mock_client.query.called
48+
49+
50+
def test_federated_view_schema_alloydb_error(
51+
monkeypatch: pytest.MonkeyPatch,
52+
capsys: pytest.CaptureFixture[str],
53+
) -> None:
54+
mock_client = mock.MagicMock()
55+
mock_job = mock.MagicMock()
56+
mock_job.result.side_effect = exceptions.NotFound("connection not found")
57+
mock_client.query.return_value = mock_job
58+
monkeypatch.setattr(
59+
bigquery_federated_view_schema_alloydb.bigquery,
60+
"Client",
61+
lambda project=None: mock_client,
62+
)
63+
64+
bigquery_federated_view_schema_alloydb.federated_view_schema_alloydb(
65+
project_id="example-project",
66+
connection_id="example-project.us-central1.example-alloydb-conn",
67+
)
68+
69+
captured = capsys.readouterr()
70+
assert "error:" in captured.err
71+
assert "example-alloydb-conn" in captured.err
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
TEST_CONFIG_OVERRIDE = {
16+
# You can opt out from the test for specific Python versions.
17+
"ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"],
18+
# Enforce type hints on new samples.
19+
"enforce_type_hints": True,
20+
"gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
21+
"pip_version_override": None,
22+
"envs": {},
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==9.0.3; python_version >= "3.10"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-cloud-bigquery==3.47.0

0 commit comments

Comments
 (0)