Query

The search machinery only works with table databases.

class pyrant.query.Query(proto, db_type, literal=False, conditions=None, columns=None, ms_type=None, ms_conditions=None)

A lazy abstraction for queries via Tyrant protocol.

You will normally instantiate Query this way:

>>> from pyrant import Tyrant
>>> t = Tyrant(host='localhost', port=1983)
>>> query = t.query

Note

the results are cached in two ways. First, the complete list of relevant keys is fetched and stored in the query object. Second, the corresponding data is fetched in large chunks depending on what slices or indices you request. Sometimes the chunks are not large enough and we hit the database too many times. To minimize the overhead you may want to increase the chunk size. You can use set_chunk_size() for that purpose.

columns(*names)

Returns a list of items with only specified columns per item. Expects names of columns to fetch. If none specified or ‘*’ is in the names, all available columns are fetched. Current query object is not modified. Returned is a list of dictionaries, not a derivative query.

Note

primary keys are not returned along with data, so this is not an equivalent for SELECT x of SQL.

Usage:

query.columns()                # fetches whole items
query.columns('*')             # same as above
query.columns('name', 'age')   # only fetches data for these columns

Warning

results are not cached in any way.

This method does not retrieve “normal” cached items and filter their contents; instead, it issues a modified search statement and retrieves pre-filtered items directly from the database. This is much faster than fetching and processing the whole bulk of data in Python.

count()
Returns the number of matched items.
delete(quick=False)

Deletes all matched items from the database. Returns True on success or False if the operation could not be performed.

Warning

current implementation is inefficient due to a bug on a lower level (probably within Pyrant). The underlying function does not tell us whether the operation was successful, so we perform an additional query. This may substantially decrease performance in some rare cases. A workaround is to use the param quick.

Parameters:
  • quick – if True, the method always returns None and does not check whether the operation was successful. Useful if you call this method very frequently. Default is False. Please note that this param will be deprecated after the underlying code is fixed so the method will always return a boolean.
exclude(*args, **kwargs)
Antipode of filter().
filter(*args, **kwargs)

Returns a clone of the Query object with given conditions applied.

Conditions can be specified as keyword arguments in this form:

t.query.filter(name__is='John', age__gte=50)

Supported keyword lookups and appropriate expression types are:

  • between: (list of numbers)
  • contains: (string or list of strings)
  • contains_any (list of strings)
  • endswith: (string)
  • exists: (boolean)
  • gt: (number)
  • gte: (number)
  • in: (list of strings or numbers)
  • is: (string, list of strings or a number)
  • like: (string or list of strings)
  • like_any: (list of strings)
  • lt (number)
  • lte (number)
  • matches (string)
  • search (string)
  • startswith (string)

If a column name is provided with no lookup, exact match (is) is assumed.

Connect to a remote table database:

>>> t.table_enabled
True

Stuff some data into the storage:

>>> t['a'] = {'name': 'Foo', 'price': 1}
>>> t['b'] = {'name': 'Bar', 'price': 2}
>>> t['c'] = {'name': 'Foo', 'price': 3}

Find everything with price > 1:

>>> for k, v in t.query.filter(price__gt=1):
...     print k
b
c

Find everything with name “Foo”:

>>> for k, v in t.query.filter(name='Foo'):
...     print k
a
c

Chain queries:

>>> cheap_items = t.query.filter(price__lt=3)
>>> cheap_bars = cheap_items.filter(name='Bar')
>>> for k, v in cheap_items:
...     print k
a
b
>>> for k, v in cheap_bars:
...     print k
b
hint()

Returns the hint string.

Warning

currently this executes the query and does not cache its results. If you fetch the results before or after calling this method, the search will be made twice.

intersect(other)
Returns a Query instance with items matched by both this query and the other one. Semantically equivalent to “a AND b”.
minus(other)
Returns a Query instance with items matched by either this query or the other but not both.
order_by(name, numeric=False)

Defines order in which results should be retrieved.

Parameters:
  • name – the column name. If prefixed with -, direction changes from ascending (default) to descending.
  • numeric – if True, values are treated as numbers. Default is False.

Examples:

q.order_by('name')     # ascending
q.order_by('-name')    # descending
q.order_by('-price', numeric=True)
set_chunk_size(size=None)

Sets cache chunk size. Makes sense only if the query has not been executed yet.

Parameters:
  • size – an int (custom size) or None (default size).

Useful if you expect a really large number of results and want to cut the number of database hits. In this case you will increase the chunk size for given query object.

Note

any existing cache for this query will be dropped.

stat()
Returns statistics on key usage.
union(other)
Returns a Query instance which items are matched either by this query or the other one or both of them. Sematically equivalent to “a OR b”.
values(key)
Returns a list of unique values for given key.

Previous topic

Protocol

This Page