Queries and Query Filters
Key-Value Storage and then some...
Get a single object
Query on a KeyField
to retrieve a single object instance.
import popoto
class Animal(popoto.Model):
name = popoto.KeyField()
sound = popoto.Field(null=True, default=None)
duck = Animal.create(name="Sally", sound="quack")
same_duck = KeyValueModel.query.get("Sally")
same_duck == duck
>>> True
Filter query results
All filter paramters are &&
AND'ed together.
import popoto
class Animal(popoto.Model):
name = popoto.KeyField()
sound = popoto.Field(null=True, default=None)
sally = Animal.create(name="Sally", sound="quack")
See (#keyfield-query-filters)[KeyField query filters] below for supported filters example:
Animal.query.filter(name__startswith="S")[0].name
>>> "salamander"
Values
Returns dictionaries, rather than model instances. Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects. Specify the fields with a tuple of field names. Each dictionary will contain only the field keys/values for the fields you specify.
Animal.query.filter(values=("name", "color"))
>>> [{"name": "salamander", "color" "green"}, ...]
Pro Tip: If all the fields specified are Key fields, then query performance will be at least 2x faster compared to a query without any specified values.
Order By field_name
Results are ordered by the value of a given field.
Movies.query.filter(order_by="-release_date")
Movies.query.filter(order_by="name")
The negative sign in front of "-release_date" indicates descending order. Ascending order is implied.
The second query will return movies ordered by name alphabetically.
ordering works for field types: str
, int
, float
, decimal
, time
, date
, datetime
Limit Number of Results
returns first 100 objects
movies = Movies.query.filter(name__startswith="The", limit=100)
len(movies)
>>> 100
the above may be slightly faster than equivalent below
movies = Movies.query.filter(name__startswith="The")[:100]
len(movies)
>>> 100
both are valid and will return the same list of objects.
if order_by is used, it will order before
Values
Returns dictionaries, rather than model instances. Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects. values requires a tuple of field names example:
Movies.query.filter(name="Life Of Pi", values=("name",))
>>> [{"name": "Life Of Pi"}, ]
KeyField query filters
{field_name}=
: exact match
{field_name}__contains=
: partial string match
{field_name}__startswith=
: partial string match
{field_name}__endswith=
: partial string match
{field_name}__in=
: is exact match for any element in provided list
SortedField query filters
{field_name}=
: exact match
{field_name}__gt=
: greater than filter
{field_name}__gte=
: greater than or equal to filter
{field_name}__lt=
: less than filter
{field_name}__lte=
: less than or equal to filter
Example Queries:
SortedFloatModel.query.filter(height__gte=john.height)
Racer.query.filter(fastest_lap__lt=55.0)
GeoField query filters
{field_name}=
: tuple
or popoto.GeoField.Coordinates
(float, float) with Coordinates
{field_name}__isnull=
: filter for null (None
) values (if null=True
is set on model field declaration)
{field_name}_latitude=
: float
{field_name}_longitude=
: float
{field_name}_radius=
: int
or float
. Default is 10
{field_name}_radius_unit=
: One of "m"
(meters), "km"
(kilometers), "ft"
(feet), "mi"
(miles). Default is "km"
(kilometers)
Example Queries:
GeoModel.query.filter(coordinates=rome.coordinates, coordinates_radius=5, coordinates_radius_unit='km')
GeoModel.query.filter(coordinates_latitude=41.902782, coordinates_longitude=12.496366)