firestore/cloud-async-client/snippets.py (461 lines of code) (raw):

# Copyright 2020 Google, Inc. # 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. import datetime from google.cloud import firestore from google.cloud.firestore_v1.base_query import FieldFilter async def quickstart_new_instance(): # [START firestore_setup_client_create_async] from google.cloud import firestore # The `project` parameter is optional and represents which project the client # will act on behalf of. If not supplied, the client falls back to the default # project inferred from the environment. db = firestore.AsyncClient(project="my-project-id") # [END firestore_setup_client_create_async] return db async def quickstart_add_data_one(): db = firestore.AsyncClient() # [START firestore_setup_dataset_pt1_async] doc_ref = db.collection("users").document("alovelace") await doc_ref.set({"first": "Ada", "last": "Lovelace", "born": 1815}) # [END firestore_setup_dataset_pt1_async] async def quickstart_add_data_two(): db = firestore.AsyncClient() # [START firestore_setup_dataset_pt2_async] doc_ref = db.collection("users").document("aturing") await doc_ref.set( {"first": "Alan", "middle": "Mathison", "last": "Turing", "born": 1912} ) # [END firestore_setup_dataset_pt2_async] async def quickstart_get_collection(): db = firestore.AsyncClient() # [START firestore_quickstart_get_collection_async] users_ref = db.collection("users") docs = users_ref.stream() async for doc in docs: print(f"{doc.id} => {doc.to_dict()}") # [END firestore_quickstart_get_collection_async] async def add_from_dict(): db = firestore.AsyncClient() # [START firestore_data_set_from_map_async] data = {"name": "Los Angeles", "state": "CA", "country": "USA"} # Add a new doc in collection 'cities' with ID 'LA' await db.collection("cities").document("LA").set(data) # [END firestore_data_set_from_map_async] async def add_data_types(): db = firestore.AsyncClient() # [START firestore_data_set_from_map_nested_async] data = { "stringExample": "Hello, World!", "booleanExample": True, "numberExample": 3.14159265, "dateExample": datetime.datetime.now(tz=datetime.timezone.utc), "arrayExample": [5, True, "hello"], "nullExample": None, "objectExample": {"a": 5, "b": True}, } await db.collection("data").document("one").set(data) # [END firestore_data_set_from_map_nested_async] # [START firestore_data_custom_type_definition_async] class City: def __init__(self, name, state, country, capital=False, population=0, regions=[]): self.name = name self.state = state self.country = country self.capital = capital self.population = population self.regions = regions @staticmethod def from_dict(source): # [START_EXCLUDE] city = City(source["name"], source["state"], source["country"]) if "capital" in source: city.capital = source["capital"] if "population" in source: city.population = source["population"] if "regions" in source: city.regions = source["regions"] return city # [END_EXCLUDE] def to_dict(self): # [START_EXCLUDE] dest = {"name": self.name, "state": self.state, "country": self.country} if self.capital: dest["capital"] = self.capital if self.population: dest["population"] = self.population if self.regions: dest["regions"] = self.regions return dest # [END_EXCLUDE] def __repr__(self): return f"City(\ name={self.name}, \ country={self.country}, \ population={self.population}, \ capital={self.capital}, \ regions={self.regions}\ )" # [END firestore_data_custom_type_definition_async] async def add_example_data(): db = firestore.AsyncClient() # [START firestore_data_get_dataset_async] cities_ref = db.collection("cities") await cities_ref.document("BJ").set( City("Beijing", None, "China", True, 21500000, ["hebei"]).to_dict() ) await cities_ref.document("SF").set( City( "San Francisco", "CA", "USA", False, 860000, ["west_coast", "norcal"] ).to_dict() ) await cities_ref.document("LA").set( City( "Los Angeles", "CA", "USA", False, 3900000, ["west_coast", "socal"] ).to_dict() ) await cities_ref.document("DC").set( City("Washington D.C.", None, "USA", True, 680000, ["east_coast"]).to_dict() ) await cities_ref.document("TOK").set( City("Tokyo", None, "Japan", True, 9000000, ["kanto", "honshu"]).to_dict() ) # [END firestore_data_get_dataset_async] async def add_custom_class_with_id(): db = firestore.AsyncClient() # [START firestore_data_set_from_custom_type_async] city = City(name="Los Angeles", state="CA", country="USA") await db.collection("cities").document("LA").set(city.to_dict()) # [END firestore_data_set_from_custom_type_async] async def add_data_with_id(): db = firestore.AsyncClient() data = {} # [START firestore_data_set_id_specified_async] await db.collection("cities").document("new-city-id").set(data) # [END firestore_data_set_id_specified_async] async def add_custom_class_generated_id(): db = firestore.AsyncClient() # [START firestore_data_set_id_random_collection_async] city = City(name="Tokyo", state=None, country="Japan") await db.collection("cities").add(city.to_dict()) # [END firestore_data_set_id_random_collection_async] async def add_new_doc(): db = firestore.AsyncClient() # [START firestore_data_set_id_random_document_ref_async] new_city_ref = db.collection("cities").document() # later... await new_city_ref.set( { # ... } ) # [END firestore_data_set_id_random_document_ref_async] async def get_check_exists(): db = firestore.AsyncClient() # [START firestore_data_get_as_map_async] doc_ref = db.collection("cities").document("SF") doc = await doc_ref.get() if doc.exists: print(f"Document data: {doc.to_dict()}") else: print("No such document!") # [END firestore_data_get_as_map_async] async def get_custom_class(): db = firestore.AsyncClient() # [START firestore_data_get_as_custom_type_async] doc_ref = db.collection("cities").document("BJ") doc = await doc_ref.get() city = City.from_dict(doc.to_dict()) print(city) # [END firestore_data_get_as_custom_type_async] async def get_simple_query(): db = firestore.AsyncClient() # [START firestore_data_query_async] # Note: Use of CollectionRef stream() is prefered to get() docs = ( db.collection("cities") .where(filter=FieldFilter("capital", "==", True)) .stream() ) async for doc in docs: print(f"{doc.id} => {doc.to_dict()}") # [END firestore_data_query_async] async def array_contains_filter(): db = firestore.AsyncClient() # [START firestore_query_filter_array_contains_async] cities_ref = db.collection("cities") query = cities_ref.where( filter=FieldFilter("regions", "array_contains", "west_coast") ) # [END firestore_query_filter_array_contains_async] docs = query.stream() async for doc in docs: print(f"{doc.id} => {doc.to_dict()}") async def get_full_collection(): db = firestore.AsyncClient() # [START firestore_data_get_all_documents_async] docs = db.collection("cities").stream() async for doc in docs: print(f"{doc.id} => {doc.to_dict()}") # [END firestore_data_get_all_documents_async] async def structure_doc_ref(): db = firestore.AsyncClient() # [START firestore_data_reference_document_async] a_lovelace_ref = db.collection("users").document("alovelace") # [END firestore_data_reference_document_async] print(a_lovelace_ref) async def structure_collection_ref(): db = firestore.AsyncClient() # [START firestore_data_reference_collection_async] users_ref = db.collection("users") # [END firestore_data_reference_collection_async] print(users_ref) async def structure_doc_ref_alternate(): db = firestore.AsyncClient() # [START firestore_data_reference_document_path_async] a_lovelace_ref = db.document("users/alovelace") # [END firestore_data_reference_document_path_async] return a_lovelace_ref async def structure_subcollection_ref(): db = firestore.AsyncClient() # [START firestore_data_reference_subcollection_async] room_a_ref = db.collection("rooms").document("roomA") message_ref = room_a_ref.collection("messages").document("message1") # [END firestore_data_reference_subcollection_async] print(message_ref) async def update_doc(): db = firestore.AsyncClient() await db.collection("cities").document("DC").set( City("Washington D.C.", None, "USA", True, 680000, ["east_coast"]).to_dict() ) # [START firestore_data_set_field_async] city_ref = db.collection("cities").document("DC") # Set the capital field await city_ref.update({"capital": True}) # [END firestore_data_set_field_async] async def update_doc_array(): db = firestore.AsyncClient() await db.collection("cities").document("DC").set( City("Washington D.C.", None, "USA", True, 680000, ["east_coast"]).to_dict() ) # [START firestore_data_set_array_operations_async] city_ref = db.collection("cities").document("DC") # Atomically add a new region to the 'regions' array field. await city_ref.update({"regions": firestore.ArrayUnion(["greater_virginia"])}) # // Atomically remove a region from the 'regions' array field. await city_ref.update({"regions": firestore.ArrayRemove(["east_coast"])}) # [END firestore_data_set_array_operations_async] city = await city_ref.get() print(f"Updated the regions field of the DC. {city.to_dict()}") async def update_multiple(): db = firestore.AsyncClient() await db.collection("cities").document("DC").set( City("Washington D.C.", None, "USA", True, 680000, ["east_coast"]).to_dict() ) # [START firestore_update_multiple_async] doc_ref = db.collection("cities").document("DC") await doc_ref.update({"name": "Washington D.C.", "country": "USA", "capital": True}) # [END firestore_update_multiple_async] async def update_create_if_missing(): db = firestore.AsyncClient() # [START firestore_data_set_doc_upsert_async] city_ref = db.collection("cities").document("BJ") await city_ref.set({"capital": True}, merge=True) # [END firestore_data_set_doc_upsert_async] async def update_nested(): db = firestore.AsyncClient() # [START firestore_data_set_nested_fields_async] # Create an initial document to update frank_ref = db.collection("users").document("frank") await frank_ref.set( { "name": "Frank", "favorites": {"food": "Pizza", "color": "Blue", "subject": "Recess"}, "age": 12, } ) # Update age and favorite color await frank_ref.update({"age": 13, "favorites.color": "Red"}) # [END firestore_data_set_nested_fields_async] async def update_server_timestamp(): db = firestore.AsyncClient() # [START firestore_data_set_server_timestamp_async] city_ref = db.collection("objects").document("some-id") await city_ref.update({"timestamp": firestore.SERVER_TIMESTAMP}) # [END firestore_data_set_server_timestamp_async] async def update_data_transaction(): db = firestore.AsyncClient() # [START firestore_transaction_document_update_async] transaction = db.transaction() city_ref = db.collection("cities").document("SF") @firestore.async_transactional async def update_in_transaction(transaction, city_ref): snapshot = await city_ref.get(transaction=transaction) transaction.update(city_ref, {"population": snapshot.get("population") + 1}) await update_in_transaction(transaction, city_ref) # [END firestore_transaction_document_update_async] async def update_data_transaction_result(): db = firestore.AsyncClient() # [START firestore_transaction_document_update_conditional_async] transaction = db.transaction() city_ref = db.collection("cities").document("SF") @firestore.async_transactional async def update_in_transaction(transaction, city_ref): snapshot = await city_ref.get(transaction=transaction) new_population = snapshot.get("population") + 1 if new_population < 1000000: transaction.update(city_ref, {"population": new_population}) return True else: return False result = await update_in_transaction(transaction, city_ref) if result: print("Population updated") else: print("Sorry! Population is too big.") # [END firestore_transaction_document_update_conditional_async] async def update_data_batch(): db = firestore.AsyncClient() # [START firestore_data_batch_writes_async] batch = db.batch() # Set the data for NYC nyc_ref = db.collection("cities").document("NYC") batch.set(nyc_ref, {"name": "New York City"}) # Update the population for SF sf_ref = db.collection("cities").document("SF") batch.update(sf_ref, {"population": 1000000}) # Delete DEN den_ref = db.collection("cities").document("DEN") batch.delete(den_ref) # Commit the batch await batch.commit() # [END firestore_data_batch_writes_async] async def compound_query_example(): db = firestore.AsyncClient() # [START firestore_query_filter_eq_string_async] # Create a reference to the cities collection cities_ref = db.collection("cities") # Create a query against the collection query_ref = cities_ref.where(filter=FieldFilter("state", "==", "CA")) # [END firestore_query_filter_eq_string_async] return query_ref async def compound_query_simple(): db = firestore.AsyncClient() # [START firestore_query_filter_eq_boolean_async] cities_ref = db.collection("cities") query = cities_ref.where(filter=FieldFilter("capital", "==", True)) # [END firestore_query_filter_eq_boolean_async] print(query) async def compound_query_single_clause(): db = firestore.AsyncClient() # [START firestore_query_filter_single_examples_async] cities_ref = db.collection("cities") cities_ref.where(filter=FieldFilter("state", "==", "CA")) cities_ref.where(filter=FieldFilter("population", "<", 1000000)) cities_ref.where(filter=FieldFilter("name", ">=", "San Francisco")) # [END firestore_query_filter_single_examples_async] async def compound_query_valid_multi_clause(): db = firestore.AsyncClient() # [START firestore_query_filter_compound_multi_eq_async] cities_ref = db.collection("cities") denver_query = cities_ref.where(filter=FieldFilter("state", "==", "CO")).where( filter=FieldFilter("name", "==", "Denver") ) large_us_cities_query = cities_ref.where( filter=FieldFilter("state", "==", "CA") ).where(filter=FieldFilter("population", ">", 1000000)) # [END firestore_query_filter_compound_multi_eq_async] print(denver_query) print(large_us_cities_query) async def compound_query_valid_single_field(): db = firestore.AsyncClient() # [START firestore_query_filter_range_valid_async] cities_ref = db.collection("cities") cities_ref.where(filter=FieldFilter("state", ">=", "CA")).where( filter=FieldFilter("state", "<=", "IN") ) # [END firestore_query_filter_range_valid_async] async def compound_query_invalid_multi_field(): db = firestore.AsyncClient() # [START firestore_query_filter_range_invalid_async] cities_ref = db.collection("cities") cities_ref.where(filter=FieldFilter("state", ">=", "CA")).where( filter=FieldFilter("population", ">=", 1000000) ) # [END firestore_query_filter_range_invalid_async] async def order_simple_limit(): db = firestore.AsyncClient() # [START firestore_order_simple_limit_async] db.collection("cities").order_by("name").limit(3).stream() # [END firestore_order_simple_limit_async] async def order_simple_limit_desc(): db = firestore.AsyncClient() # [START firestore_query_order_desc_limit_async] cities_ref = db.collection("cities") query = cities_ref.order_by("name", direction=firestore.Query.DESCENDING).limit(3) results = query.stream() # [END firestore_query_order_desc_limit_async] print(results) async def order_multiple(): db = firestore.AsyncClient() # [START firestore_query_order_multi_async] cities_ref = db.collection("cities") cities_ref.order_by("state").order_by( "population", direction=firestore.Query.DESCENDING ) # [END firestore_query_order_multi_async] async def order_where_limit(): db = firestore.AsyncClient() # [START firestore_query_order_limit_field_valid_async] cities_ref = db.collection("cities") query = ( cities_ref.where(filter=FieldFilter("population", ">", 2500000)) .order_by("population") .limit(2) ) results = query.stream() # [END firestore_query_order_limit_field_valid_async] print([d async for d in results]) async def order_limit_to_last(): db = firestore.AsyncClient() # [START firestore_query_order_limit_async] cities_ref = db.collection("cities") query = cities_ref.order_by("name").limit_to_last(2) results = await query.get() # [END firestore_query_order_limit_async] print(results) async def order_where_valid(): db = firestore.AsyncClient() # [START firestore_query_order_with_filter_async] cities_ref = db.collection("cities") query = cities_ref.where(filter=FieldFilter("population", ">", 2500000)).order_by( "population" ) results = query.stream() # [END firestore_query_order_with_filter_async] print([d async for d in results]) async def order_where_invalid(): db = firestore.AsyncClient() # [START firestore_query_order_field_invalid_async] cities_ref = db.collection("cities") query = cities_ref.where(filter=FieldFilter("population", ">", 2500000)).order_by( "country" ) results = query.stream() # [END firestore_query_order_field_invalid_async] print(results) async def cursor_simple_start_at(): db = firestore.AsyncClient() # [START firestore_query_cursor_start_at_field_value_single_async] cities_ref = db.collection("cities") query_start_at = cities_ref.order_by("population").start_at({"population": 1000000}) # [END firestore_query_cursor_start_at_field_value_single_async] return query_start_at async def cursor_simple_end_at(): db = firestore.AsyncClient() # [START firestore_query_cursor_end_at_field_value_single_async] cities_ref = db.collection("cities") query_end_at = cities_ref.order_by("population").end_at({"population": 1000000}) # [END firestore_query_cursor_end_at_field_value_single_async] return query_end_at async def snapshot_cursors(): db = firestore.AsyncClient() # [START firestore_query_cursor_start_at_document_async] doc_ref = db.collection("cities").document("SF") snapshot = await doc_ref.get() start_at_snapshot = ( db.collection("cities").order_by("population").start_at(snapshot) ) # [END firestore_query_cursor_start_at_document_async] results = start_at_snapshot.limit(10).stream() async for doc in results: print(f"{doc.id}") return results async def cursor_paginate(): db = firestore.AsyncClient() # [START firestore_query_cursor_pagination_async] cities_ref = db.collection("cities") first_query = cities_ref.order_by("population").limit(3) # Get the last document from the results docs = [d async for d in first_query.stream()] last_doc = list(docs)[-1] # Construct a new query starting at this document # Note: this will not have the desired effect if # multiple cities have the exact same population value last_pop = last_doc.to_dict()["population"] next_query = ( cities_ref.order_by("population").start_after({"population": last_pop}).limit(3) ) # Use the query for pagination # ... # [END firestore_query_cursor_pagination_async] return next_query async def cursor_multiple_conditions(): db = firestore.AsyncClient() # [START firestore_query_cursor_start_at_field_value_multi_async] start_at_name = ( db.collection("cities") .order_by("name") .order_by("state") .start_at({"name": "Springfield"}) ) start_at_name_and_state = ( db.collection("cities") .order_by("name") .order_by("state") .start_at({"name": "Springfield", "state": "Missouri"}) ) # [END firestore_query_cursor_start_at_field_value_multi_async] return start_at_name, start_at_name_and_state async def delete_single_doc(): db = firestore.AsyncClient() # [START firestore_data_delete_doc_async] await db.collection("cities").document("DC").delete() # [END firestore_data_delete_doc_async] async def delete_field(): db = firestore.AsyncClient() # [START firestore_data_delete_field_async] city_ref = db.collection("cities").document("BJ") await city_ref.update({"capital": firestore.DELETE_FIELD}) # [END firestore_data_delete_field_async] async def delete_full_collection(): db = firestore.AsyncClient() # [START firestore_data_delete_collection_async] async def delete_collection(coll_ref, batch_size): docs = coll_ref.limit(batch_size).stream() deleted = 0 async for doc in docs: print(f"Deleting doc {doc.id} => {doc.to_dict()}") await doc.reference.delete() deleted = deleted + 1 if deleted >= batch_size: return delete_collection(coll_ref, batch_size) # [END firestore_data_delete_collection_async] await delete_collection(db.collection("cities"), 10) await delete_collection(db.collection("data"), 10) await delete_collection(db.collection("objects"), 10) await delete_collection(db.collection("users"), 10) async def collection_group_query(db): # [START firestore_query_collection_group_dataset_async] cities = db.collection("cities") sf_landmarks = cities.document("SF").collection("landmarks") await sf_landmarks.document().set({"name": "Golden Gate Bridge", "type": "bridge"}) await sf_landmarks.document().set({"name": "Legion of Honor", "type": "museum"}) la_landmarks = cities.document("LA").collection("landmarks") await la_landmarks.document().set({"name": "Griffith Park", "type": "park"}) await la_landmarks.document().set({"name": "The Getty", "type": "museum"}) dc_landmarks = cities.document("DC").collection("landmarks") await dc_landmarks.document().set({"name": "Lincoln Memorial", "type": "memorial"}) await dc_landmarks.document().set( {"name": "National Air and Space Museum", "type": "museum"} ) tok_landmarks = cities.document("TOK").collection("landmarks") await tok_landmarks.document().set({"name": "Ueno Park", "type": "park"}) await tok_landmarks.document().set( {"name": "National Museum of Nature and Science", "type": "museum"} ) bj_landmarks = cities.document("BJ").collection("landmarks") await bj_landmarks.document().set({"name": "Jingshan Park", "type": "park"}) await bj_landmarks.document().set( {"name": "Beijing Ancient Observatory", "type": "museum"} ) # [END firestore_query_collection_group_dataset_async] # [START firestore_query_collection_group_filter_eq_async] museums = db.collection_group("landmarks").where( filter=FieldFilter("type", "==", "museum") ) docs = museums.stream() async for doc in docs: print(f"{doc.id} => {doc.to_dict()}") # [END firestore_query_collection_group_filter_eq_async] return docs async def array_contains_any_queries(db): # [START firestore_query_filter_array_contains_any_async] cities_ref = db.collection("cities") query = cities_ref.where( filter=FieldFilter( "regions", "array_contains_any", ["west_coast", "east_coast"] ) ) return query # [END firestore_query_filter_array_contains_any_async] async def in_query_without_array(db): # [START firestore_query_filter_in_async] cities_ref = db.collection("cities") query = cities_ref.where(filter=FieldFilter("country", "in", ["USA", "Japan"])) return query # [END firestore_query_filter_in_async] async def in_query_with_array(db): # [START firestore_query_filter_in_with_array_async] cities_ref = db.collection("cities") query = cities_ref.where( filter=FieldFilter("regions", "in", [["west_coast"], ["east_coast"]]) ) return query # [END firestore_query_filter_in_with_array_async] async def update_document_increment(db): # [START firestore_data_set_numeric_increment_async] washington_ref = db.collection("cities").document("DC") await washington_ref.update({"population": firestore.Increment(50)}) # [END firestore_data_set_numeric_increment_async] async def list_document_subcollections(): db = firestore.AsyncClient() # [START firestore_data_get_sub_collections_async] collections = db.collection("cities").document("SF").collections() async for collection in collections: async for doc in collection.stream(): print(f"{doc.id} => {doc.to_dict()}") # [END firestore_data_get_sub_collections_async]