Skip to content

Commit

Permalink
docs: Update docstrings for django_spanner (#564)
Browse files Browse the repository at this point in the history
  • Loading branch information
mf2199 committed Dec 16, 2020
1 parent 77834f3 commit 7083f1d
Show file tree
Hide file tree
Showing 13 changed files with 957 additions and 27 deletions.
45 changes: 44 additions & 1 deletion django_spanner/base.py
Expand Up @@ -103,6 +103,11 @@ class DatabaseWrapper(BaseDatabaseWrapper):

@property
def instance(self):
"""Reference to a Cloud Spanner Instance containing the Database.
:rtype: :class:`~google.cloud.spanner_v1.instance.Instance`
:returns: A new instance owned by the existing Spanner Client.
"""
return spanner.Client().instance(self.settings_dict["INSTANCE"])

@property
Expand All @@ -112,6 +117,12 @@ def _nodb_connection(self):
)

def get_connection_params(self):
"""Retrieve the connection parameters.
:rtype: dict
:returns: A dictionary containing the Spanner connection parameters
in Django Spanner format.
"""
return {
"project": self.settings_dict["PROJECT"],
"instance_id": self.settings_dict["INSTANCE"],
Expand All @@ -120,20 +131,52 @@ def get_connection_params(self):
**self.settings_dict["OPTIONS"],
}

def get_new_connection(self, conn_params):
def get_new_connection(self, **conn_params):
"""Create a new connection with corresponding connection parameters.
:type conn_params: list
:param conn_params: A List of the connection parameters for
:class:`~google.cloud.spanner_dbapi.connection.Connection`
:rtype: :class:`google.cloud.spanner_dbapi.connection.Connection`
:returns: A new Spanner DB API Connection object associated with the
given Google Cloud Spanner resource.
:raises: :class:`ValueError` in case the given instance/database
doesn't exist.
"""
return Database.connect(**conn_params)

def init_connection_state(self):
"""Initialize the state of the existing connection."""
pass

def create_cursor(self, name=None):
"""Create a new Database cursor.
:type name: str
:param name: Currently not used.
:rtype: :class:`~google.cloud.spanner_dbapi.cursor.Cursor`
:returns: The Cursor for this connection.
"""
return self.connection.cursor()

def _set_autocommit(self, autocommit):
"""Set the Spanner transaction autocommit flag.
:type autocommit: bool
:param autocommit: The new value of the autocommit flag.
"""
with self.wrap_database_errors:
self.connection.autocommit = autocommit

def is_usable(self):
"""Check whether the connection is valid.
:rtype: bool
:returns: True if the connection is open, otherwise False.
"""
if self.connection is None:
return False
try:
Expand Down
2 changes: 2 additions & 0 deletions django_spanner/client.py
Expand Up @@ -9,5 +9,7 @@


class DatabaseClient(BaseDatabaseClient):
"""Wrap the Django base class."""

def runshell(self, parameters):
raise NotSupportedError("This method is not supported.")
22 changes: 21 additions & 1 deletion django_spanner/compiler.py
Expand Up @@ -17,11 +17,27 @@


class SQLCompiler(BaseSQLCompiler):
"""
A variation of the Django SQL compiler, adjusted for Spanner-specific
functionality.
"""

def get_combinator_sql(self, combinator, all):
"""
"""Override the native Django method.
Copied from the base class except for:
combinator_sql += ' ALL' if all else ' DISTINCT'
Cloud Spanner requires ALL or DISTINCT.
:type combinator: str
:param combinator: A type of the combinator for the operation.
:type all: bool
:param all: Bool option for the SQL statement.
:rtype: tuple
:returns: A tuple containing SQL statement(s) with some additional
parameters.
"""
features = self.connection.features
compilers = [
Expand Down Expand Up @@ -97,16 +113,20 @@ def get_combinator_sql(self, combinator, all):


class SQLInsertCompiler(BaseSQLInsertCompiler, SQLCompiler):
"""A wrapper class for compatibility with Django specifications."""
pass


class SQLDeleteCompiler(BaseSQLDeleteCompiler, SQLCompiler):
"""A wrapper class for compatibility with Django specifications."""
pass


class SQLUpdateCompiler(BaseSQLUpdateCompiler, SQLCompiler):
"""A wrapper class for compatibility with Django specifications."""
pass


class SQLAggregateCompiler(BaseSQLAggregateCompiler, SQLCompiler):
"""A wrapper class for compatibility with Django specifications."""
pass
15 changes: 15 additions & 0 deletions django_spanner/creation.py
Expand Up @@ -14,6 +14,11 @@


class DatabaseCreation(BaseDatabaseCreation):
"""
Spanner-specific wrapper for Django class encapsulating methods for
creation and destruction of the underlying test database.
"""

def mark_skips(self):
"""Skip tests that don't work on Spanner."""
for test_name in self.connection.features.skip_tests:
Expand All @@ -30,13 +35,23 @@ def mark_skips(self):
)

def create_test_db(self, *args, **kwargs):
"""Create a test database.
:rtype: str
:returns: The name of the newly created test Database.
"""
# This environment variable is set by the Travis build script or
# by a developer running the tests locally.
if os.environ.get("RUNNING_SPANNER_BACKEND_TESTS") == "1":
self.mark_skips()
super().create_test_db(*args, **kwargs)

def _create_test_db(self, verbosity, autoclobber, keepdb=False):
"""
Create dummy test tables. This method is mostly copied from the
base class but removes usage of `_nodb_connection` since Spanner doesn't
have or need one.
"""
# Mostly copied from the base class but removes usage of
# _nodb_connection since Spanner doesn't have or need one.
test_database_name = self._get_test_db_name()
Expand Down
13 changes: 11 additions & 2 deletions django_spanner/expressions.py
Expand Up @@ -8,8 +8,16 @@


def order_by(self, compiler, connection, **extra_context):
# In Django 3.1, this can be replaced with
# DatabaseFeatures.supports_order_by_nulls_modifier = False.
"""
Order expressions in the SQL query and generate a new query using
Spanner-specific templates.
:rtype: str
:returns: A SQL query.
"""
# TODO: In Django 3.1, this can be replaced with
# DatabaseFeatures.supports_order_by_nulls_modifier = False.
# Also, consider making this a class method.
template = None
if self.nulls_last:
template = "%(expression)s IS NULL, %(expression)s %(ordering)s"
Expand All @@ -21,4 +29,5 @@ def order_by(self, compiler, connection, **extra_context):


def register_expressions():
"""Add Spanner-specific attribute to the Django OrderBy class."""
OrderBy.as_spanner = order_by
1 change: 1 addition & 0 deletions django_spanner/features.py
Expand Up @@ -11,6 +11,7 @@


class DatabaseFeatures(BaseDatabaseFeatures):
"""An extension to Django database feature descriptor."""
can_introspect_big_integer_field = False
can_introspect_duration_field = False
can_introspect_foreign_keys = False
Expand Down

0 comments on commit 7083f1d

Please sign in to comment.