Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
feat: add
Database.list_tables
method (#219)
* feat: add `Database.list_tables` method * update docs, add tests * remove numeric from get_schema test The NUMERIC column is not included in the emulator system tests. * add unit tests * add docs for table api and usage * fix link to Field class * typo in table constructor docs * add reload and exists methods * feat: add table method to database * update usage docs to use factory method * address warning in GitHub UI for sphinx header * Update docs/table-usage.rst Co-authored-by: larkee <31196561+larkee@users.noreply.github.com>
- Loading branch information
Showing
with
428 additions
and 2 deletions.
- +1 −0 docs/api-reference.rst
- +1 −0 docs/index.rst
- +6 −0 docs/table-api.rst
- +47 −0 docs/table-usage.rst
- +42 −1 google/cloud/spanner_v1/database.py
- +1 −1 google/cloud/spanner_v1/instance.py
- +126 −0 google/cloud/spanner_v1/table.py
- +60 −0 tests/system/test_system.py
- +20 −0 tests/unit/test_database.py
- +124 −0 tests/unit/test_table.py
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -10,6 +10,7 @@ Most likely, you will be interacting almost exclusively with these: | ||
client-api | ||
instance-api | ||
database-api | ||
table-api | ||
session-api | ||
keyset-api | ||
snapshot-api | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -11,6 +11,7 @@ Usage Documentation | ||
client-usage | ||
instance-usage | ||
database-usage | ||
table-usage | ||
batch-usage | ||
snapshot-usage | ||
transaction-usage | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,6 @@ | ||
Table API | ||
========= | ||
|
||
.. automodule:: google.cloud.spanner_v1.table | ||
:members: | ||
:show-inheritance: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,47 @@ | ||
Table Admin | ||
=========== | ||
|
||
After creating an :class:`~google.cloud.spanner_v1.database.Database`, you can | ||
interact with individual tables for that instance. | ||
|
||
|
||
List Tables | ||
----------- | ||
|
||
To iterate over all existing tables for an database, use its | ||
:meth:`~google.cloud.spanner_v1.database.Database.list_tables` method: | ||
|
||
.. code:: python | ||
for table in database.list_tables(): | ||
# `table` is a `Table` object. | ||
This method yields :class:`~google.cloud.spanner_v1.table.Table` objects. | ||
|
||
|
||
Table Factory | ||
------------- | ||
|
||
A :class:`~google.cloud.spanner_v1.table.Table` object can be created with the | ||
:meth:`~google.cloud.spanner_v1.database.Database.table` factory method: | ||
|
||
.. code:: python | ||
table = database.table("my_table_id") | ||
if table.exists(): | ||
print("Table with ID 'my_table' exists.") | ||
else: | ||
print("Table with ID 'my_table' does not exist." | ||
Getting the Table Schema | ||
------------------------ | ||
Use the :attr:`~google.cloud.spanner_v1.table.Table.schema` property to inspect | ||
the columns of a table as a list of | ||
:class:`~google.cloud.spanner_v1.types.StructType.Field` objects. | ||
.. code:: python | ||
for field in table.schema | ||
# `field` is a `Field` object. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,126 @@ | ||
# Copyright 2021 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""User friendly container for Cloud Spanner Table.""" | ||
|
||
from google.cloud.exceptions import NotFound | ||
|
||
from google.cloud.spanner_v1.types import ( | ||
Type, | ||
TypeCode, | ||
) | ||
|
||
|
||
_EXISTS_TEMPLATE = """ | ||
SELECT EXISTS( | ||
SELECT TABLE_NAME | ||
FROM INFORMATION_SCHEMA.TABLES | ||
WHERE TABLE_NAME = @table_id | ||
) | ||
""" | ||
_GET_SCHEMA_TEMPLATE = "SELECT * FROM {} LIMIT 0" | ||
|
||
|
||
class Table(object): | ||
"""Representation of a Cloud Spanner Table. | ||
:type table_id: str | ||
:param table_id: The ID of the table. | ||
:type database: :class:`~google.cloud.spanner_v1.database.Database` | ||
:param database: The database that owns the table. | ||
""" | ||
|
||
def __init__(self, table_id, database): | ||
self._table_id = table_id | ||
self._database = database | ||
|
||
# Calculated properties. | ||
self._schema = None | ||
|
||
@property | ||
def table_id(self): | ||
"""The ID of the table used in SQL. | ||
:rtype: str | ||
:returns: The table ID. | ||
""" | ||
return self._table_id | ||
|
||
def exists(self): | ||
"""Test whether this table exists. | ||
:rtype: bool | ||
:returns: True if the table exists, else false. | ||
""" | ||
with self._database.snapshot() as snapshot: | ||
return self._exists(snapshot) | ||
|
||
def _exists(self, snapshot): | ||
"""Query to check that the table exists. | ||
:type snapshot: :class:`~google.cloud.spanner_v1.snapshot.Snapshot` | ||
:param snapshot: snapshot to use for database queries | ||
:rtype: bool | ||
:returns: True if the table exists, else false. | ||
""" | ||
results = snapshot.execute_sql( | ||
_EXISTS_TEMPLATE, | ||
params={"table_id": self.table_id}, | ||
param_types={"table_id": Type(code=TypeCode.STRING)}, | ||
) | ||
return next(iter(results))[0] | ||
|
||
@property | ||
def schema(self): | ||
"""The schema of this table. | ||
:rtype: list of :class:`~google.cloud.spanner_v1.types.StructType.Field` | ||
:returns: The table schema. | ||
""" | ||
if self._schema is None: | ||
with self._database.snapshot() as snapshot: | ||
self._schema = self._get_schema(snapshot) | ||
return self._schema | ||
|
||
def _get_schema(self, snapshot): | ||
"""Get the schema of this table. | ||
:type snapshot: :class:`~google.cloud.spanner_v1.snapshot.Snapshot` | ||
:param snapshot: snapshot to use for database queries | ||
:rtype: list of :class:`~google.cloud.spanner_v1.types.StructType.Field` | ||
:returns: The table schema. | ||
""" | ||
query = _GET_SCHEMA_TEMPLATE.format(self.table_id) | ||
results = snapshot.execute_sql(query) | ||
# Start iterating to force the schema to download. | ||
try: | ||
next(iter(results)) | ||
except StopIteration: | ||
pass | ||
return list(results.fields) | ||
|
||
def reload(self): | ||
"""Reload this table. | ||
Refresh any configured schema into :attr:`schema`. | ||
:raises NotFound: if the table does not exist | ||
""" | ||
with self._database.snapshot() as snapshot: | ||
if not self._exists(snapshot): | ||
raise NotFound("table '{}' does not exist".format(self.table_id)) | ||
self._schema = self._get_schema(snapshot) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.