def test_get_nested_value_nested(): from google.cloud.firestore_v1 import field_path assert field_path.get_nested_value("top1.middle2", DATA) is DATA["top1"]["middle2"] assert (field_path.get_nested_value("top1.middle2.bottom3", DATA) is DATA["top1"]["middle2"]["bottom3"])
def test_get_nested_value_bad_type(): from google.cloud.firestore_v1 import field_path from google.cloud.firestore_v1.field_path import _FIELD_PATH_WRONG_TYPE with pytest.raises(KeyError) as exc_info: field_path.get_nested_value("top6.middle7", DATA) err_msg = _FIELD_PATH_WRONG_TYPE.format("top6", "middle7") assert exc_info.value.args == (err_msg, )
def test_get_nested_value_missing_key(): from google.cloud.firestore_v1 import field_path from google.cloud.firestore_v1.field_path import _FIELD_PATH_MISSING_KEY with pytest.raises(KeyError) as exc_info: field_path.get_nested_value("top1.middle2.nope", DATA) err_msg = _FIELD_PATH_MISSING_KEY.format("nope", "top1.middle2") assert exc_info.value.args == (err_msg, )
def test_get_nested_value_missing_top_level(): from google.cloud.firestore_v1 import field_path from google.cloud.firestore_v1.field_path import _FIELD_PATH_MISSING_TOP path = "top8" with pytest.raises(KeyError) as exc_info: field_path.get_nested_value(path, DATA) err_msg = _FIELD_PATH_MISSING_TOP.format(path) assert exc_info.value.args == (err_msg, )
def _normalize_cursor(self, cursor, orders) -> Optional[Tuple[Any, Any]]: """Helper: convert cursor to a list of values based on orders.""" if cursor is None: return if not orders: raise ValueError(_NO_ORDERS_FOR_CURSOR) document_fields, before = cursor order_keys = [order.field.field_path for order in orders] if isinstance(document_fields, document.DocumentSnapshot): snapshot = document_fields document_fields = snapshot.to_dict() document_fields["__name__"] = snapshot.reference if isinstance(document_fields, dict): # Transform to list using orders values = [] data = document_fields # It isn't required that all order by have a cursor. # However, we need to be sure they are specified in order without gaps for order_key in order_keys[:len(data)]: try: if order_key in data: values.append(data[order_key]) else: values.append( field_path_module.get_nested_value( order_key, data)) except KeyError: msg = _MISSING_ORDER_BY.format(order_key, data) raise ValueError(msg) document_fields = values if document_fields and len(document_fields) > len(orders): msg = _MISMATCH_CURSOR_W_ORDER_BY.format(document_fields, order_keys) raise ValueError(msg) _transform_bases = (transforms.Sentinel, transforms._ValueList) for index, key_field in enumerate(zip(order_keys, document_fields)): key, field = key_field if isinstance(field, _transform_bases): msg = _INVALID_CURSOR_TRANSFORM raise ValueError(msg) if key == "__name__" and isinstance(field, str): document_fields[index] = self._parent.document(field) return document_fields, before
def _normalize_cursor(self, cursor, orders): """Helper: convert cursor to a list of values based on orders.""" if cursor is None: return if not orders: raise ValueError(_NO_ORDERS_FOR_CURSOR) document_fields, before = cursor order_keys = [order.field.field_path for order in orders] if isinstance(document_fields, document.DocumentSnapshot): snapshot = document_fields document_fields = snapshot.to_dict() document_fields["__name__"] = snapshot.reference if isinstance(document_fields, dict): # Transform to list using orders values = [] data = document_fields for order_key in order_keys: try: if order_key in data: values.append(data[order_key]) else: values.append( field_path_module.get_nested_value( order_key, data)) except KeyError: msg = _MISSING_ORDER_BY.format(order_key, data) raise ValueError(msg) document_fields = values if len(document_fields) != len(orders): msg = _MISMATCH_CURSOR_W_ORDER_BY.format(document_fields, order_keys) raise ValueError(msg) _transform_bases = (transforms.Sentinel, transforms._ValueList) for index, key_field in enumerate(zip(order_keys, document_fields)): key, field = key_field if isinstance(field, _transform_bases): msg = _INVALID_CURSOR_TRANSFORM raise ValueError(msg) if key == "__name__" and isinstance(field, six.string_types): document_fields[index] = self._parent.document(field) return document_fields, before
def _normalize_cursor(self, cursor, orders): """Helper: convert cursor to a list of values based on orders.""" if cursor is None: return if not orders: raise ValueError(_NO_ORDERS_FOR_CURSOR) document_fields, before = cursor order_keys = [order.field.field_path for order in orders] if isinstance(document_fields, document.DocumentSnapshot): snapshot = document_fields document_fields = snapshot.to_dict() document_fields["__name__"] = snapshot.reference if isinstance(document_fields, dict): # Transform to list using orders values = [] data = document_fields for order_key in order_keys: try: values.append(field_path_module.get_nested_value(order_key, data)) except KeyError: msg = _MISSING_ORDER_BY.format(order_key, data) raise ValueError(msg) document_fields = values if len(document_fields) != len(orders): msg = _MISMATCH_CURSOR_W_ORDER_BY.format(document_fields, order_keys) raise ValueError(msg) _transform_bases = (transforms.Sentinel, transforms._ValueList) for index, key_field in enumerate(zip(order_keys, document_fields)): key, field = key_field if isinstance(field, _transform_bases): msg = _INVALID_CURSOR_TRANSFORM raise ValueError(msg) if key == "__name__" and isinstance(field, six.string_types): document_fields[index] = self._parent.document(field) return document_fields, before
def get(self, field_path): """Get a value from the snapshot data. If the data is nested, for example: .. code-block:: python >>> snapshot.to_dict() { 'top1': { 'middle2': { 'bottom3': 20, 'bottom4': 22, }, 'middle5': True, }, 'top6': b'\x00\x01 foo', } a **field path** can be used to access the nested data. For example: .. code-block:: python >>> snapshot.get('top1') { 'middle2': { 'bottom3': 20, 'bottom4': 22, }, 'middle5': True, } >>> snapshot.get('top1.middle2') { 'bottom3': 20, 'bottom4': 22, } >>> snapshot.get('top1.middle2.bottom3') 20 See :meth:`~google.cloud.firestore_v1.client.Client.field_path` for more information on **field paths**. A copy is returned since the data may contain mutable values, but the data stored in the snapshot must remain immutable. Args: field_path (str): A field path (``.``-delimited list of field names). Returns: Any or None: (A copy of) the value stored for the ``field_path`` or None if snapshot document does not exist. Raises: KeyError: If the ``field_path`` does not match nested data in the snapshot. """ if not self._exists: return None nested_data = field_path_module.get_nested_value(field_path, self._data) return copy.deepcopy(nested_data)
def get(self, field_path: str) -> Any: """Get a value from the snapshot data. If the data is nested, for example: .. code-block:: python >>> snapshot.to_dict() { 'top1': { 'middle2': { 'bottom3': 20, 'bottom4': 22, }, 'middle5': True, }, 'top6': b'\x00\x01 foo', } a **field path** can be used to access the nested data. For example: .. code-block:: python >>> snapshot.get('top1') { 'middle2': { 'bottom3': 20, 'bottom4': 22, }, 'middle5': True, } >>> snapshot.get('top1.middle2') { 'bottom3': 20, 'bottom4': 22, } >>> snapshot.get('top1.middle2.bottom3') 20 See :meth:`~google.cloud.firestore_v1.client.Client.field_path` for more information on **field paths**. A copy is returned since the data may contain mutable values, but the data stored in the snapshot must remain immutable. Args: field_path (str): A field path (``.``-delimited list of field names). Returns: Any or None: (A copy of) the value stored for the ``field_path`` or None if snapshot document does not exist. Raises: KeyError: If the ``field_path`` does not match nested data in the snapshot. """ if not self._exists: return None nested_data = field_path_module.get_nested_value( field_path, self._data) return copy.deepcopy(nested_data)
def test_get_nested_value_simple(): from google.cloud.firestore_v1 import field_path assert field_path.get_nested_value("top1", DATA) is DATA["top1"]
def _call_fut(path, data): from google.cloud.firestore_v1 import field_path return field_path.get_nested_value(path, data)
def _call_fut(path, data): from google.cloud.firestore_v1 import field_path return field_path.get_nested_value(path, data)