.. _querying: Querying Objects ================ The InfiniBox API layer allows its users to query and sort objects according to various criteria. InfiniSDK offers a clean Pythonic syntax to perform such queries. Querying All Objects -------------------- Querying all objects can be done by iterating over the collection proxies (e.g. ``system.volumes``): .. code-block:: python >>> system.volumes.count() 5 >>> for volume in system.volumes: ... print("Found volume:", volume.get_name()) Found volume: vol0 Found volume: vol1 Found volume: vol2 Found volume: vol3 Found volume: vol4 .. note:: This is also equivalent to iterating over ``system.volumes.find()`` Querying by Fields ------------------ Querying by fields is relatively easy if you want a specific field value: .. code-block:: python >>> [v] = system.volumes.find(name='vol0') >>> v # doctest: +ELLIPSIS <...:Volume id=...> Getting a Single Object ----------------------- Getting a single object has an even easier shortcut -- ``get``, which assumes only one object is returned: >>> v = system.volumes.get(name='vol0') >>> v # doctest: +ELLIPSIS <...:Volume id=...> It will fail if either 0 or several objects are returned: .. code-block:: python >>> system.volumes.get() # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... TooManyObjectsFound >>> system.volumes.get(name='nonexistent') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ObjectNotFound There is also ``safe_get``, returning ``None`` instead of raising an exception if no object is found: .. code-block:: python >>> system.volumes.safe_get(name='nonexistent') is None True Advanced Queries ---------------- Object fields can be used to perform more complex queries, using operators. For instance, here is a query for all volumes whose name is not 'vol1'. .. code-block:: python >>> for v in system.volumes.find(system.volumes.fields.name != 'vol1'): ... print(v.get_name()) vol0 vol2 vol3 vol4 The above code leverages Python's operator overloading to generate on-the-fly query filters. There is also a shorter syntax for writing the above piece of code, using the ``Q`` shortcut available from InfiniSDK: .. code-block:: python >>> from infinisdk import Q >>> vols = system.volumes.find(Q.name != 'vol1') >>> len(vols) 4 .. note:: ``Q.x != y`` is merely a shortcut for ``SomeObject.fields.x != y``, and provides no other additional functionality besides shortening the syntax. .. note:: You can use the following operators ``==``, ``!=``, ``>``, ``>=``, ``<``, ``<=``, and also ``.in_(...)``, ``.not_in(...)``, ``.between(x, y)`` and ``.like("string")``. Not all operators are supported by all queries -- some limitations might apply. And here is a query to find all volumes greater than 1 GiB in size: .. code-block:: python >>> from capacity import GiB >>> system.volumes.find(system.volumes.fields.size > GiB).to_list() [] .. seealso:: :ref:`capacities`