core.db.query ============= .. py:module:: core.db.query Attributes ---------- .. autoapisummary:: core.db.query.TOrderHook core.db.query.TFilterHook Classes ------- .. autoapisummary:: core.db.query.Query Functions --------- .. autoapisummary:: core.db.query._entryMatchesQuery Module Contents --------------- .. py:data:: TOrderHook .. py:data:: TFilterHook .. py:function:: _entryMatchesQuery(entry, singleFilter) Utility function which checks if the given entity could have been returned by a query filtering by the properties in singleFilter. This can be used if a list of entities have been retrieved (e.g. by a 3rd party full text search engine) and these have now to be checked against the filter returned by their modules :meth:`viur.core.prototypes.list.listFilter` method. :param entry: The entity which will be tested :param singleFilter: A dictionary containing all the filters from the query :return: True if the entity could have been returned by such an query, False otherwise .. py:class:: Query(kind, srcSkelClass = None, *args, **kwargs) Bases: :py:obj:`object` Base Class for querying the datastore. Its API is similar to the google.cloud.datastore.query API, but it provides the necessary hooks for relational or random queries, the fulltext search as well as support for IN filters. Constructs a new Query. :param kind: The kind to run this query on. This may be later overridden to run on a different kind (like viur-relations), but it's guaranteed to return only entities of that kind. :param srcSkelClass: If set, enables data-model depended queries (like relational queries) as well as the :meth:fetch method .. py:attribute:: kind .. py:attribute:: srcSkel :value: None .. py:attribute:: queries :type: Union[None, core.db.types.QueryDefinition, List[core.db.types.QueryDefinition]] .. py:attribute:: _filterHook :type: TFilterHook | None :value: None .. py:attribute:: _orderHook :type: TOrderHook | None :value: None .. py:attribute:: _customMultiQueryMerge :type: Union[None, Callable[[Query, List[List[core.db.types.Entity]], int], List[core.db.types.Entity]]] :value: None .. py:attribute:: _calculateInternalMultiQueryLimit :type: Union[None, Callable[[Query, int], int]] :value: None .. py:attribute:: customQueryInfo .. py:attribute:: origKind .. py:attribute:: _lastEntry :value: None .. py:attribute:: _fulltextQueryString :type: Union[None, str] :value: None .. py:attribute:: lastCursor :value: None .. py:method:: setFilterHook(hook) Installs *hook* as a callback function for new filters. *hook* will be called each time a new filter constrain is added to the query. This allows e.g. the relationalBone to rewrite constrains added after the initial processing of the query has been done (e.g. by ``listFilter()`` methods). :param hook: The function to register as callback. A value of None removes the currently active hook. :returns: The previously registered hook (if any), or None. .. py:method:: setOrderHook(hook) Installs *hook* as a callback function for new orderings. *hook* will be called each time a :func:`db.Query.order` is called on this query. :param hook: The function to register as callback. A value of None removes the currently active hook. :returns: The previously registered hook (if any), or None. .. py:method:: mergeExternalFilter(filters) Safely merges filters according to the data model. Its only valid to call this function if the query has been created using :func:`core.skeleton.Skeleton.all`. It's safe to pass filters received from an external source (a user); unknown/invalid filters will be ignored, so the query-object is kept in a valid state even when processing malformed data. If complex queries are needed (e.g. filter by relations), this function shall also be used. See also :meth:`filter` for simple filters. :param filters: A dictionary of attributes and filter pairs. :returns: Returns the query itself for chaining. .. py:method:: filter(prop, value) Adds a new constraint to this query. See also :meth:`mergeExternalFilter` for a safer filter implementation. :param prop: Name of the property + operation we'll filter by :param value: The value of that filter. :returns: Returns the query itself for chaining. .. py:method:: order(*orderings) Specify a query sorting. Resulting entities will be sorted by the first property argument, then by the second, and so on. The following example .. code-block:: python query = Query("Person") query.order(("bday" db.SortOrder.Ascending), ("age", db.SortOrder.Descending)) sorts every Person in order of their birthday, starting with January 1. People with the same birthday are sorted by age, oldest to youngest. ``order()`` may be called multiple times. Each call resets the sort order from scratch. If an inequality filter exists in this Query it must be the first property passed to ``order()``. t.Any number of sort orders may be used after the inequality filter property. Without inequality filters, any number of filters with different orders may be specified. Entities with multiple values for an order property are sorted by their lowest value. Note that a sort order implies an existence filter! In other words, Entities without the sort order property are filtered out, and *not* included in the query results. If the sort order property has different types in different entities - e.g. if bob["id"] is an int and fred["id"] is a string - the entities will be grouped first by the property type, then sorted within type. No attempt is made to compare property values across types. :param orderings: The properties to sort by, in sort order. Each argument must be a (name, direction) 2-tuple. :returns: Returns the query itself for chaining. .. py:method:: setCursor(startCursor, endCursor = None) Sets the start and optionally end cursor for this query. The result set will only include results between these cursors. The cursor is generated by an earlier query with exactly the same configuration. It's safe to use client-supplied cursors, a cursor can't be abused to access entities which don't match the current filters. :param startCursor: The start cursor for this query. :param endCursor: The end cursor for this query. :returns: Returns the query itself for chaining. .. py:method:: limit(limit) Sets the query limit to *limit* entities in the result. :param limit: The maximum number of entities per batch. :returns: Returns the query itself for chaining. .. py:method:: distinctOn(keyList) Ensure only entities with distinct values on the fields listed are returned. This will implicitly override your SortOrder as all fields listed in keyList have to be sorted first. .. py:method:: getCursor() Get a valid cursor from the last run of this query. The source of this cursor varies depending on what the last call was: - :meth:`run`: A cursor that points immediately behind the last result pulled off the returned iterator. - :meth:`get`: A cursor that points immediately behind the last result in the returned list. :returns: A cursor that can be used in subsequent query requests or None if that query does not support cursors or there are no more elements to fetch .. py:method:: get_orders() Get the orders from this query. :returns: The orders form this query as a list if there is no orders set it returns None .. py:method:: getKind() :returns: the *current* kind of this query. This may not be the kind this query has been constructed with as relational bones may rewrite this. .. py:method:: _run_single_filter_query(query, limit) Internal helper function that runs a single query definition on the datastore and returns a list of entities found. :param query: The querydefinition (filters, orders, distinct etc.) to run against the datastore :param limit: How many results should at most be returned :return: The first *limit* entities that matches this query .. py:method:: _merge_multi_query_results(input_result) Merge the lists of entries into a single list; removing duplicates and restoring sort-order :param input_result: Nested Lists of Entries returned by each individual query run :return: Sorted & deduplicated list of entries .. py:method:: _resort_result(entities, filters, orders) Internal helper that takes a (deduplicated) list of entities that has been fetched from different internal queries (the datastore does not support IN filters itself, so we have to query each item in that array separately) and resorts the list so it matches the query again. :param entities: t.List of entities to resort :param filters: The filter used in the query (used to determine implicit sort order by an inequality filter) :param orders: The sort-orders to apply :return: The sorted list .. py:method:: _fixKind(resultList) Jump to parentKind if necessary (used in relations) .. py:method:: run(limit = -1) Run this query. It is more efficient to use *limit* if the number of results is known. If queried data is wanted as instances of Skeletons, :meth:`fetch` should be used. :param limit: Limits the query to the defined maximum entities. :returns: The list of found entities :raises: :exc:`BadFilterError` if a filter string is invalid :raises: :exc:`BadValueError` if a filter value is invalid. :raises: :exc:`BadQueryError` if an IN filter in combination with a sort order on another property is provided .. py:method:: count(up_to = 2**63 - 1) The count operation cost one entity read for up to 1,000 index entries matched (https://cloud.google.com/datastore/docs/aggregation-queries#pricing) :param up_to can be sigend int 64 bit (max positive 2^31-1) :returns: Count entries for this query. .. py:method:: fetch(limit = -1) Run this query and fetch results as :class:`core.skeleton.SkelList`. This function is similar to :meth:`run`, but returns a :class:`core.skeleton.SkelList` instance instead of Entities. :warning: The query must be limited! If queried data is wanted as instances of Entity, :meth:`run` should be used. :param limit: Limits the query to the defined maximum entities. :raises: :exc:`BadFilterError` if a filter string is invalid :raises: :exc:`BadValueError` if a filter value is invalid. :raises: :exc:`BadQueryError` if an IN filter in combination with a sort order on another property is provided .. py:method:: iter() Run this query and return an iterator for the results. The advantage of this function is, that it allows for iterating over a large result-set, as it hasn't have to be pulled in advance from the datastore. This function intentionally ignores a limit set by :meth:`limit`. :warning: If iterating over a large result set, make sure the query supports cursors. Otherwise, it might not return all results as the AppEngine doesn't maintain the view for a query for more than ~30 seconds. .. py:method:: getEntry() Returns only the first entity of the current query. :returns: The first entity on success, or None if the result-set is empty. .. py:method:: getSkel() Returns a matching :class:`core.db.skeleton.Skeleton` instance for the current query. It's only possible to use this function if this query has been created using :func:`core.skeleton.Skeleton.all`. :returns: The Skeleton or None if the result-set is empty. .. py:method:: clone() Returns a deep copy of the current query. :returns: The cloned query. .. py:method:: __repr__()