Skip to content

Commit 255895d

Browse files
authored
Firestore: rename 'Query.get' -> 'stream'. (#7284)
Leave 'Query.get' as a deprecated alias for 'Query.stream'. Closes #6558.
1 parent ae5a0b7 commit 255895d

File tree

5 files changed

+132
-35
lines changed

5 files changed

+132
-35
lines changed

packages/google-cloud-firestore/google/cloud/firestore_v1beta1/collection.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
# limitations under the License.
1414

1515
"""Classes for representing collections for the Google Cloud Firestore API."""
16-
17-
1816
import random
17+
import warnings
1918

2019
import six
2120

@@ -384,6 +383,15 @@ def end_at(self, document_fields):
384383
return query.end_at(document_fields)
385384

386385
def get(self, transaction=None):
386+
"""Deprecated alias for :meth:`stream`."""
387+
warnings.warn(
388+
"'Collection.get' is deprecated: please use 'Collection.stream' instead.",
389+
DeprecationWarning,
390+
stacklevel=2,
391+
)
392+
return self.stream(transaction=transaction)
393+
394+
def stream(self, transaction=None):
387395
"""Read the documents in this collection.
388396
389397
This sends a ``RunQuery`` RPC and then returns an iterator which
@@ -411,7 +419,7 @@ def get(self, transaction=None):
411419
document that fulfills the query.
412420
"""
413421
query = query_mod.Query(self)
414-
return query.get(transaction=transaction)
422+
return query.stream(transaction=transaction)
415423

416424
def on_snapshot(self, callback):
417425
"""Monitor the documents in this collection.

packages/google-cloud-firestore/google/cloud/firestore_v1beta1/query.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818
a :class:`~.firestore_v1beta1.collection.Collection` and that can be
1919
a more common way to create a query than direct usage of the constructor.
2020
"""
21-
22-
2321
import copy
2422
import math
23+
import warnings
2524

2625
from google.protobuf import wrappers_pb2
2726
import six
@@ -696,6 +695,15 @@ def _to_protobuf(self):
696695
return query_pb2.StructuredQuery(**query_kwargs)
697696

698697
def get(self, transaction=None):
698+
"""Deprecated alias for :meth:`stream`."""
699+
warnings.warn(
700+
"'Query.get' is deprecated: please use 'Query.stream' instead.",
701+
DeprecationWarning,
702+
stacklevel=2,
703+
)
704+
return self.stream(transaction=transaction)
705+
706+
def stream(self, transaction=None):
699707
"""Read the documents in the collection that match this query.
700708
701709
This sends a ``RunQuery`` RPC and then returns an iterator which

packages/google-cloud-firestore/tests/system.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ def test_collection_add(client, cleanup):
483483
assert set(collection3.list_documents()) == {document_ref5}
484484

485485

486-
def test_query_get(client, cleanup):
486+
def test_query_stream(client, cleanup):
487487
sub_collection = "child" + unique_resource_id("-")
488488
collection = client.collection("collek", "shun", sub_collection)
489489

@@ -504,15 +504,15 @@ def test_query_get(client, cleanup):
504504

505505
# 0. Limit to snapshots where ``a==1``.
506506
query0 = collection.where("a", "==", 1)
507-
values0 = {snapshot.id: snapshot.to_dict() for snapshot in query0.get()}
507+
values0 = {snapshot.id: snapshot.to_dict() for snapshot in query0.stream()}
508508
assert len(values0) == num_vals
509509
for key, value in six.iteritems(values0):
510510
assert stored[key] == value
511511
assert value["a"] == 1
512512

513513
# 1. Order by ``b``.
514514
query1 = collection.order_by("b", direction=query0.DESCENDING)
515-
values1 = [(snapshot.id, snapshot.to_dict()) for snapshot in query1.get()]
515+
values1 = [(snapshot.id, snapshot.to_dict()) for snapshot in query1.stream()]
516516
assert len(values1) == len(stored)
517517
b_vals1 = []
518518
for key, value in values1:
@@ -523,7 +523,7 @@ def test_query_get(client, cleanup):
523523

524524
# 2. Limit to snapshots where ``stats.sum > 1`` (a field path).
525525
query2 = collection.where("stats.sum", ">", 4)
526-
values2 = {snapshot.id: snapshot.to_dict() for snapshot in query2.get()}
526+
values2 = {snapshot.id: snapshot.to_dict() for snapshot in query2.stream()}
527527
assert len(values2) == 10
528528
ab_pairs2 = set()
529529
for key, value in six.iteritems(values2):
@@ -546,7 +546,7 @@ def test_query_get(client, cleanup):
546546
.start_at({"a": num_vals - 2})
547547
.end_before({"a": num_vals - 1})
548548
)
549-
values3 = [(snapshot.id, snapshot.to_dict()) for snapshot in query3.get()]
549+
values3 = [(snapshot.id, snapshot.to_dict()) for snapshot in query3.stream()]
550550
assert len(values3) == num_vals
551551
for key, value in values3:
552552
assert stored[key] == value
@@ -555,13 +555,13 @@ def test_query_get(client, cleanup):
555555

556556
# 4. Send a query with no results.
557557
query4 = collection.where("b", "==", num_vals + 100)
558-
values4 = list(query4.get())
558+
values4 = list(query4.stream())
559559
assert len(values4) == 0
560560

561561
# 5. Select a subset of fields.
562562
query5 = collection.where("b", "<=", 1)
563563
query5 = query5.select(["a", "stats.product"])
564-
values5 = {snapshot.id: snapshot.to_dict() for snapshot in query5.get()}
564+
values5 = {snapshot.id: snapshot.to_dict() for snapshot in query5.stream()}
565565
assert len(values5) == num_vals * 2 # a ANY, b in (0, 1)
566566
for key, value in six.iteritems(values5):
567567
expected = {
@@ -573,7 +573,7 @@ def test_query_get(client, cleanup):
573573
# 6. Add multiple filters via ``where()``.
574574
query6 = collection.where("stats.product", ">", 5)
575575
query6 = query6.where("stats.product", "<", 10)
576-
values6 = {snapshot.id: snapshot.to_dict() for snapshot in query6.get()}
576+
values6 = {snapshot.id: snapshot.to_dict() for snapshot in query6.stream()}
577577

578578
matching_pairs = [
579579
(a_val, b_val)
@@ -591,7 +591,7 @@ def test_query_get(client, cleanup):
591591
query7 = collection.where("b", "==", 2)
592592
offset = 3
593593
query7 = query7.offset(offset)
594-
values7 = {snapshot.id: snapshot.to_dict() for snapshot in query7.get()}
594+
values7 = {snapshot.id: snapshot.to_dict() for snapshot in query7.stream()}
595595
# NOTE: We don't check the ``a``-values, since that would require
596596
# an ``order_by('a')``, which combined with the ``b == 2``
597597
# filter would necessitate an index.
@@ -617,15 +617,15 @@ def test_query_unary(client, cleanup):
617617

618618
# 0. Query for null.
619619
query0 = collection.where(field_name, "==", None)
620-
values0 = list(query0.get())
620+
values0 = list(query0.stream())
621621
assert len(values0) == 1
622622
snapshot0 = values0[0]
623623
assert snapshot0.reference._path == document0._path
624624
assert snapshot0.to_dict() == {field_name: None}
625625

626626
# 1. Query for a NAN.
627627
query1 = collection.where(field_name, "==", nan_val)
628-
values1 = list(query1.get())
628+
values1 = list(query1.stream())
629629
assert len(values1) == 1
630630
snapshot1 = values1[0]
631631
assert snapshot1.reference._path == document1._path
@@ -813,7 +813,7 @@ def on_snapshot(docs, changes, read_time):
813813
on_snapshot.called_count += 1
814814

815815
# A snapshot should return the same thing as if a query ran now.
816-
query_ran = db.collection(u"users").where("first", "==", u"Ada").get()
816+
query_ran = db.collection(u"users").where("first", "==", u"Ada").stream()
817817
assert len(docs) == len([i for i in query_ran])
818818

819819
on_snapshot.called_count = 0
@@ -856,7 +856,7 @@ def on_snapshot(docs, changes, read_time):
856856
if len(docs) != 5:
857857
return
858858
# A snapshot should return the same thing as if a query ran now.
859-
query_ran = query_ref.get()
859+
query_ran = query_ref.stream()
860860
query_ran_results = [i for i in query_ran]
861861
assert len(docs) == len(query_ran_results)
862862

packages/google-cloud-firestore/tests/unit/test_collection.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -497,24 +497,59 @@ def test_list_documents_w_page_size(self):
497497

498498
@mock.patch("google.cloud.firestore_v1beta1.query.Query", autospec=True)
499499
def test_get(self, query_class):
500+
import warnings
501+
500502
collection = self._make_one("collection")
501-
get_response = collection.get()
503+
with warnings.catch_warnings(record=True) as warned:
504+
get_response = collection.get()
502505

503506
query_class.assert_called_once_with(collection)
504507
query_instance = query_class.return_value
505-
self.assertIs(get_response, query_instance.get.return_value)
506-
query_instance.get.assert_called_once_with(transaction=None)
508+
self.assertIs(get_response, query_instance.stream.return_value)
509+
query_instance.stream.assert_called_once_with(transaction=None)
510+
511+
# Verify the deprecation
512+
self.assertEqual(len(warned), 1)
513+
self.assertIs(warned[0].category, DeprecationWarning)
507514

508515
@mock.patch("google.cloud.firestore_v1beta1.query.Query", autospec=True)
509516
def test_get_with_transaction(self, query_class):
517+
import warnings
518+
519+
collection = self._make_one("collection")
520+
transaction = mock.sentinel.txn
521+
with warnings.catch_warnings(record=True) as warned:
522+
get_response = collection.get(transaction=transaction)
523+
524+
query_class.assert_called_once_with(collection)
525+
query_instance = query_class.return_value
526+
self.assertIs(get_response, query_instance.stream.return_value)
527+
query_instance.stream.assert_called_once_with(transaction=transaction)
528+
529+
# Verify the deprecation
530+
self.assertEqual(len(warned), 1)
531+
self.assertIs(warned[0].category, DeprecationWarning)
532+
533+
@mock.patch("google.cloud.firestore_v1beta1.query.Query", autospec=True)
534+
def test_stream(self, query_class):
535+
collection = self._make_one("collection")
536+
stream_response = collection.stream()
537+
538+
query_class.assert_called_once_with(collection)
539+
query_instance = query_class.return_value
540+
self.assertIs(stream_response, query_instance.stream.return_value)
541+
query_instance.stream.assert_called_once_with(transaction=None)
542+
543+
@mock.patch("google.cloud.firestore_v1beta1.query.Query", autospec=True)
544+
def test_stream_with_transaction(self, query_class):
510545
collection = self._make_one("collection")
511546
transaction = mock.sentinel.txn
512-
get_response = collection.get(transaction=transaction)
547+
stream_response = collection.stream(transaction=transaction)
513548

514549
query_class.assert_called_once_with(collection)
515550
query_instance = query_class.return_value
516-
self.assertIs(get_response, query_instance.get.return_value)
517-
query_instance.get.assert_called_once_with(transaction=transaction)
551+
self.assertIs(stream_response, query_instance.stream.return_value)
552+
query_instance.stream.assert_called_once_with(transaction=transaction)
518553

519554
@mock.patch("google.cloud.firestore_v1beta1.collection.Watch", autospec=True)
520555
def test_on_snapshot(self, watch):

packages/google-cloud-firestore/tests/unit/test_query.py

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,52 @@ def test__to_protobuf_limit_only(self):
10141014
self.assertEqual(structured_query_pb, expected_pb)
10151015

10161016
def test_get_simple(self):
1017+
import warnings
1018+
1019+
# Create a minimal fake GAPIC.
1020+
firestore_api = mock.Mock(spec=["run_query"])
1021+
1022+
# Attach the fake GAPIC to a real client.
1023+
client = _make_client()
1024+
client._firestore_api_internal = firestore_api
1025+
1026+
# Make a **real** collection reference as parent.
1027+
parent = client.collection("dee")
1028+
1029+
# Add a dummy response to the minimal fake GAPIC.
1030+
_, expected_prefix = parent._parent_info()
1031+
name = "{}/sleep".format(expected_prefix)
1032+
data = {"snooze": 10}
1033+
response_pb = _make_query_response(name=name, data=data)
1034+
firestore_api.run_query.return_value = iter([response_pb])
1035+
1036+
# Execute the query and check the response.
1037+
query = self._make_one(parent)
1038+
1039+
with warnings.catch_warnings(record=True) as warned:
1040+
get_response = query.get()
1041+
1042+
self.assertIsInstance(get_response, types.GeneratorType)
1043+
returned = list(get_response)
1044+
self.assertEqual(len(returned), 1)
1045+
snapshot = returned[0]
1046+
self.assertEqual(snapshot.reference._path, ("dee", "sleep"))
1047+
self.assertEqual(snapshot.to_dict(), data)
1048+
1049+
# Verify the mock call.
1050+
parent_path, _ = parent._parent_info()
1051+
firestore_api.run_query.assert_called_once_with(
1052+
parent_path,
1053+
query._to_protobuf(),
1054+
transaction=None,
1055+
metadata=client._rpc_metadata,
1056+
)
1057+
1058+
# Verify the deprecation
1059+
self.assertEqual(len(warned), 1)
1060+
self.assertIs(warned[0].category, DeprecationWarning)
1061+
1062+
def test_stream_simple(self):
10171063
# Create a minimal fake GAPIC.
10181064
firestore_api = mock.Mock(spec=["run_query"])
10191065

@@ -1033,7 +1079,7 @@ def test_get_simple(self):
10331079

10341080
# Execute the query and check the response.
10351081
query = self._make_one(parent)
1036-
get_response = query.get()
1082+
get_response = query.stream()
10371083
self.assertIsInstance(get_response, types.GeneratorType)
10381084
returned = list(get_response)
10391085
self.assertEqual(len(returned), 1)
@@ -1050,7 +1096,7 @@ def test_get_simple(self):
10501096
metadata=client._rpc_metadata,
10511097
)
10521098

1053-
def test_get_with_transaction(self):
1099+
def test_stream_with_transaction(self):
10541100
# Create a minimal fake GAPIC.
10551101
firestore_api = mock.Mock(spec=["run_query"])
10561102

@@ -1075,7 +1121,7 @@ def test_get_with_transaction(self):
10751121

10761122
# Execute the query and check the response.
10771123
query = self._make_one(parent)
1078-
get_response = query.get(transaction=transaction)
1124+
get_response = query.stream(transaction=transaction)
10791125
self.assertIsInstance(get_response, types.GeneratorType)
10801126
returned = list(get_response)
10811127
self.assertEqual(len(returned), 1)
@@ -1091,7 +1137,7 @@ def test_get_with_transaction(self):
10911137
metadata=client._rpc_metadata,
10921138
)
10931139

1094-
def test_get_no_results(self):
1140+
def test_stream_no_results(self):
10951141
# Create a minimal fake GAPIC with a dummy response.
10961142
firestore_api = mock.Mock(spec=["run_query"])
10971143
empty_response = _make_query_response()
@@ -1106,7 +1152,7 @@ def test_get_no_results(self):
11061152
parent = client.collection("dah", "dah", "dum")
11071153
query = self._make_one(parent)
11081154

1109-
get_response = query.get()
1155+
get_response = query.stream()
11101156
self.assertIsInstance(get_response, types.GeneratorType)
11111157
self.assertEqual(list(get_response), [])
11121158

@@ -1119,7 +1165,7 @@ def test_get_no_results(self):
11191165
metadata=client._rpc_metadata,
11201166
)
11211167

1122-
def test_get_second_response_in_empty_stream(self):
1168+
def test_stream_second_response_in_empty_stream(self):
11231169
# Create a minimal fake GAPIC with a dummy response.
11241170
firestore_api = mock.Mock(spec=["run_query"])
11251171
empty_response1 = _make_query_response()
@@ -1135,7 +1181,7 @@ def test_get_second_response_in_empty_stream(self):
11351181
parent = client.collection("dah", "dah", "dum")
11361182
query = self._make_one(parent)
11371183

1138-
get_response = query.get()
1184+
get_response = query.stream()
11391185
self.assertIsInstance(get_response, types.GeneratorType)
11401186
self.assertEqual(list(get_response), [])
11411187

@@ -1148,7 +1194,7 @@ def test_get_second_response_in_empty_stream(self):
11481194
metadata=client._rpc_metadata,
11491195
)
11501196

1151-
def test_get_with_skipped_results(self):
1197+
def test_stream_with_skipped_results(self):
11521198
# Create a minimal fake GAPIC.
11531199
firestore_api = mock.Mock(spec=["run_query"])
11541200

@@ -1169,7 +1215,7 @@ def test_get_with_skipped_results(self):
11691215

11701216
# Execute the query and check the response.
11711217
query = self._make_one(parent)
1172-
get_response = query.get()
1218+
get_response = query.stream()
11731219
self.assertIsInstance(get_response, types.GeneratorType)
11741220
returned = list(get_response)
11751221
self.assertEqual(len(returned), 1)
@@ -1186,7 +1232,7 @@ def test_get_with_skipped_results(self):
11861232
metadata=client._rpc_metadata,
11871233
)
11881234

1189-
def test_get_empty_after_first_response(self):
1235+
def test_stream_empty_after_first_response(self):
11901236
# Create a minimal fake GAPIC.
11911237
firestore_api = mock.Mock(spec=["run_query"])
11921238

@@ -1207,7 +1253,7 @@ def test_get_empty_after_first_response(self):
12071253

12081254
# Execute the query and check the response.
12091255
query = self._make_one(parent)
1210-
get_response = query.get()
1256+
get_response = query.stream()
12111257
self.assertIsInstance(get_response, types.GeneratorType)
12121258
returned = list(get_response)
12131259
self.assertEqual(len(returned), 1)

0 commit comments

Comments
 (0)