Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Commit 40a60e3

Browse files
committed
update docs, add tests
1 parent 3f9cc92 commit 40a60e3

3 files changed

Lines changed: 75 additions & 7 deletions

File tree

google/cloud/spanner_v1/database.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@
4747
)
4848
from google.cloud.spanner_admin_database_v1 import CreateDatabaseRequest
4949
from google.cloud.spanner_admin_database_v1 import UpdateDatabaseDdlRequest
50-
from google.cloud.spanner_v1 import ExecuteSqlRequest
51-
from google.cloud.spanner_v1.table import Table
52-
from google.cloud.spanner_v1.proto.transaction_pb2 import (
50+
from google.cloud.spanner_v1 import (
51+
ExecuteSqlRequest,
5352
TransactionSelector,
5453
TransactionOptions,
5554
)
55+
from google.cloud.spanner_v1.table import Table
5656

5757
# pylint: enable=ungrouped-imports
5858

google/cloud/spanner_v1/table.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,39 @@
1919

2020
class Table(object):
2121
"""Representation of a Cloud Spanner Table.
22+
23+
:type table_id: str
24+
:param table_id: The ID of the table.
25+
26+
:type instance: :class:`~google.cloud.spanner_v1.database.Database`
27+
:param instance: The database that owns the table.
2228
"""
2329

2430
def __init__(self, table_id, database):
25-
self.table_id = table_id
31+
self._table_id = table_id
2632
self._database = database
2733

28-
def get_schema(self):
34+
@property
35+
def table_id(self):
36+
"""The ID of the table used in SQL.
37+
38+
:rtype: str
39+
:returns: The table ID.
2940
"""
30-
List of google.cloud.spanner_v1.types.Field
41+
return self._table_id
42+
43+
def get_schema(self):
44+
"""Get the schema of this table.
45+
46+
:rtype: list of :class:`~google.cloud.spanner_v1.types.Field`
47+
:returns: The table schema.
3148
"""
3249
with self._database.snapshot() as snapshot:
3350
query = _GET_SCHEMA_TEMPLATE.format(self.table_id)
3451
results = snapshot.execute_sql(query)
35-
# _ = list(results)
52+
# Start iterating to force the schema to download.
53+
try:
54+
next(iter(results))
55+
except StopIteration:
56+
pass
3657
return list(results.fields)

tests/system/test_system.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from google.cloud.spanner_v1 import KeySet
4343
from google.cloud.spanner_v1.instance import Backup
4444
from google.cloud.spanner_v1.instance import Instance
45+
from google.cloud.spanner_v1.table import Table
4546

4647
from test_utils.retry import RetryErrors
4748
from test_utils.retry import RetryInstanceState
@@ -465,6 +466,52 @@ def _unit_of_work(transaction, name):
465466
self.assertEqual(len(rows), 2)
466467

467468

469+
class TestTableAPI(unittest.TestCase, _TestData):
470+
DATABASE_NAME = "test_database" + unique_resource_id("_")
471+
472+
@classmethod
473+
def setUpClass(cls):
474+
pool = BurstyPool(labels={"testcase": "database_api"})
475+
ddl_statements = EMULATOR_DDL_STATEMENTS if USE_EMULATOR else DDL_STATEMENTS
476+
cls._db = Config.INSTANCE.database(
477+
cls.DATABASE_NAME, ddl_statements=ddl_statements, pool=pool
478+
)
479+
operation = cls._db.create()
480+
operation.result(30) # raises on failure / timeout.
481+
482+
@classmethod
483+
def tearDownClass(cls):
484+
cls._db.drop()
485+
486+
def test_list_tables(self):
487+
tables = self._db.list_tables()
488+
table_ids = set(table.table_id for table in tables)
489+
self.assertIn("contacts", table_ids)
490+
self.assertIn("contact_phones", table_ids)
491+
self.assertIn("all_types", table_ids)
492+
493+
def test_list_tables_get_schema(self):
494+
tables = self._db.list_tables()
495+
for table in tables:
496+
schema = table.get_schema()
497+
self.assertIsInstance(schema, list)
498+
499+
def test_get_schema(self):
500+
table = Table("all_types", self._db)
501+
schema = table.get_schema()
502+
names_and_types = set((field.name, field.type_.code) for field in schema)
503+
self.assertIn(("pkey", TypeCode.INT64), names_and_types)
504+
self.assertIn(("int_value", TypeCode.INT64), names_and_types)
505+
self.assertIn(("int_array", TypeCode.ARRAY), names_and_types)
506+
self.assertIn(("bool_value", TypeCode.BOOL), names_and_types)
507+
self.assertIn(("bytes_value", TypeCode.BYTES), names_and_types)
508+
self.assertIn(("date_value", TypeCode.DATE), names_and_types)
509+
self.assertIn(("float_value", TypeCode.FLOAT64), names_and_types)
510+
self.assertIn(("string_value", TypeCode.STRING), names_and_types)
511+
self.assertIn(("timestamp_value", TypeCode.TIMESTAMP), names_and_types)
512+
self.assertIn(("numeric_value", TypeCode.NUMERIC), names_and_types)
513+
514+
468515
@unittest.skipIf(USE_EMULATOR, "Skipping backup tests")
469516
@unittest.skipIf(SKIP_BACKUP_TESTS, "Skipping backup tests")
470517
class TestBackupAPI(unittest.TestCase, _TestData):

0 commit comments

Comments
 (0)