forked from googleapis/google-cloud-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Drop 'Database.read' and 'Database.execute_sql' convenience methods. (g…
…oogleapis#3787) Because the context managers they use returned the session to the database's pool, application code could not safely iterate over the result sets returned by the methods. Update docs for 'Snapshot.read' and 'Snapshot.execute_sql' to emphasize iteration of their results sets before the session is returned to the database pool (i.e., within the 'with' block which constructs the snapshot). Closes googleapis#3769.
- Loading branch information
Showing
4 changed files
with
42 additions
and
138 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,12 +45,22 @@ fails if the result set is too large, | |
|
||
.. code:: python | ||
result = snapshot.read( | ||
table='table-name', columns=['first_name', 'last_name', 'age'], | ||
key_set=['[email protected]', '[email protected]']) | ||
with database.snapshot() as snapshot: | ||
result = snapshot.read( | ||
table='table-name', columns=['first_name', 'last_name', 'age'], | ||
key_set=['[email protected]', '[email protected]']) | ||
for row in result.rows: | ||
print(row) | ||
for row in result.rows: | ||
print(row) | ||
.. note:: | ||
|
||
The result set returned by | ||
:meth:`~google.cloud.spanner.snapshot.Snapshot.execute_sql` *must not* be | ||
iterated after the snapshot's session has been returned to the database's | ||
session pool. Therefore, unless your application creates sessions | ||
manually, perform all iteration within the context of the | ||
``with database.snapshot()`` block. | ||
|
||
.. note:: | ||
|
||
|
@@ -68,14 +78,24 @@ fails if the result set is too large, | |
|
||
.. code:: python | ||
QUERY = ( | ||
'SELECT e.first_name, e.last_name, p.telephone ' | ||
'FROM employees as e, phones as p ' | ||
'WHERE p.employee_id == e.employee_id') | ||
result = snapshot.execute_sql(QUERY) | ||
with database.snapshot() as snapshot: | ||
QUERY = ( | ||
'SELECT e.first_name, e.last_name, p.telephone ' | ||
'FROM employees as e, phones as p ' | ||
'WHERE p.employee_id == e.employee_id') | ||
result = snapshot.execute_sql(QUERY) | ||
for row in result.rows: | ||
print(row) | ||
.. note:: | ||
|
||
for row in result.rows: | ||
print(row) | ||
The result set returned by | ||
:meth:`~google.cloud.spanner.snapshot.Snapshot.execute_sql` *must not* be | ||
iterated after the snapshot's session has been returned to the database's | ||
session pool. Therefore, unless your application creates sessions | ||
manually, perform all iteration within the context of the | ||
``with database.snapshot()`` block. | ||
|
||
|
||
Next Step | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -621,21 +621,6 @@ def test_session_factory(self): | |
self.assertIs(session.session_id, None) | ||
self.assertIs(session._database, database) | ||
|
||
def test_execute_sql_defaults(self): | ||
QUERY = 'SELECT * FROM employees' | ||
client = _Client() | ||
instance = _Instance(self.INSTANCE_NAME, client=client) | ||
pool = _Pool() | ||
session = _Session() | ||
pool.put(session) | ||
session._execute_result = [] | ||
database = self._make_one(self.DATABASE_ID, instance, pool=pool) | ||
|
||
rows = list(database.execute_sql(QUERY)) | ||
|
||
self.assertEqual(rows, []) | ||
self.assertEqual(session._executed, (QUERY, None, None, None, b'')) | ||
|
||
def test_run_in_transaction_wo_args(self): | ||
import datetime | ||
|
||
|
@@ -678,38 +663,6 @@ def test_run_in_transaction_w_args(self): | |
self.assertEqual(session._retried, | ||
(_unit_of_work, (SINCE,), {'until': UNTIL})) | ||
|
||
def test_read(self): | ||
from google.cloud.spanner.keyset import KeySet | ||
|
||
TABLE_NAME = 'citizens' | ||
COLUMNS = ['email', 'first_name', 'last_name', 'age'] | ||
KEYS = ['[email protected]', '[email protected]'] | ||
KEYSET = KeySet(keys=KEYS) | ||
INDEX = 'email-address-index' | ||
LIMIT = 20 | ||
TOKEN = b'DEADBEEF' | ||
client = _Client() | ||
instance = _Instance(self.INSTANCE_NAME, client=client) | ||
pool = _Pool() | ||
session = _Session() | ||
pool.put(session) | ||
database = self._make_one(self.DATABASE_ID, instance, pool=pool) | ||
|
||
rows = list(database.read( | ||
TABLE_NAME, COLUMNS, KEYSET, INDEX, LIMIT, TOKEN)) | ||
|
||
self.assertEqual(rows, []) | ||
|
||
(table, columns, key_set, index, limit, | ||
resume_token) = session._read_with | ||
|
||
self.assertEqual(table, TABLE_NAME) | ||
self.assertEqual(columns, COLUMNS) | ||
self.assertEqual(key_set, KEYSET) | ||
self.assertEqual(index, INDEX) | ||
self.assertEqual(limit, LIMIT) | ||
self.assertEqual(resume_token, TOKEN) | ||
|
||
def test_batch(self): | ||
from google.cloud.spanner.database import BatchCheckout | ||
|
||
|
@@ -951,18 +904,10 @@ def __init__(self, database=None, name=_BaseTest.SESSION_NAME): | |
self._database = database | ||
self.name = name | ||
|
||
def execute_sql(self, sql, params, param_types, query_mode, resume_token): | ||
self._executed = (sql, params, param_types, query_mode, resume_token) | ||
return iter(self._rows) | ||
|
||
def run_in_transaction(self, func, *args, **kw): | ||
self._retried = (func, args, kw) | ||
return self._committed | ||
|
||
def read(self, table, columns, keyset, index, limit, resume_token): | ||
self._read_with = (table, columns, keyset, index, limit, resume_token) | ||
return iter(self._rows) | ||
|
||
|
||
class _SessionPB(object): | ||
name = TestDatabase.SESSION_NAME | ||
|