QuerySet
- class sheraf.queryset.QuerySet(iterable=None, model_class=None, predicate=None, primary_key=None, **kwargs)[source]
Bases:
objectA
QuerySetis a collection containingModelinstances. Like in a regularset, objects are unique, but the main difference is thatQuerySetkeeps the insertion order.- Parameters:
iterable (Iterable) – A collection of models. If iterable is None, then model must be set.
model_class – A model class to iterate over. If model is None, then iterable must be set. If both are set, model_class is ignored.
predicate (Predicate) – a callable takes an instance as parameter and return a Boolean (if True, the instance will be returned in the iteration). If None, everything is returned.
kwargs – A dictionnary containing the values expected from the model parameters. If kwargs is {“foo”: “bar”} then the queryset will only contains models which attribute foo is “bar”.
For the following examples, let us work with a simple Cowboy model. For the sake of simplicity we use a
IntOrderedNamedAttributesModelso the first instance created will have id 0, the second will have id 1 and so on…>>> class Cowboy(sheraf.IntOrderedNamedAttributesModel): ... table = "queryset_people" ... name = sheraf.SimpleAttribute() ... age = sheraf.SimpleAttribute() ... >>> with sheraf.connection(commit=True): ... peter = Cowboy.create(name="Peter", age=30) ... steven = Cowboy.create(name="Steven", age=30) ... george = Cowboy.create(name="George Abitbol", age=50)
QuerySetare mostly created by doing requests on a Model withall(),filter()ororder(), but can also be initialized with custom data.>>> with sheraf.connection(): ... a = Cowboy.all() # returns a QuerySet with all Cowboy ... b = QuerySet([peter, steven, george]) # This is an equivalent custom QuerySet ... assert list(a) == list(b)
QuerySetbehave like iterators, and can only be consumed once.>>> with sheraf.connection(): ... everybody = Cowboy.all() ... assert [peter, steven, george] == list(everybody) ... assert [] == everybody
Note
QuerySetcan be compared against anything iterable, but the comparison will consume theQuerySet.QuerySetkeeps the order of insertion.>>> assert QuerySet([peter, steven]) != QuerySet([steven, peter])
QuerySetsupports slicing. Slices returns anotherQuerySet.>>> with sheraf.connection(): ... assert peter == Cowboy.all()[0] ... assert QuerySet([peter, steven]) == Cowboy.all()[0:2] ... assert QuerySet([peter, steven, george]) == Cowboy.all()[0:]
- copy()[source]
Copies the
QuerySetwithout consuming it.>>> with sheraf.connection(): ... peter = Cowboy.create(name="Peter") ... steven = Cowboy.create(name="Steven") ... george = Cowboy.create(name="George") ... qall = Cowboy.all() ... qcopy = qall.copy() ... ... assert [peter, steven, george] == qall ... # now qall is consumed ... ... assert [peter, steven, george] == qcopy ... # now qcopy is consumed
- delete()[source]
Delete the objects contained in the queryset.
Avoids problems when itering on deleted objects.
- filter(predicate=None, **kwargs)[source]
Refine a copy of the current
QuerySetwith further tests.- Parameters:
predicate (callable object) – filter instance by returning a truthy value. If None everything is selected.
kwargs (A dictionary which keys must be valid attributes of the model iterated.) – A dictionnary containing the values expected from the model parameters. If
kwargsis{"foo": "bar"}then the queryset will only contains models which attributefoois"bar".
- Returns:
A copy of the current
QuerySetrefined with further tests.- Return type:
It is possible to chain
filter()calls:>>> with sheraf.connection(): ... assert Cowboy.filter(name="George Abitbol", age=50) == \ ... Cowboy.filter(name="George Abitbol").filter(age=50) ... >>> with sheraf.connection(): ... assert Cowboy.filter(lambda person: "Abitbol" in person.name, age=50) == \ ... Cowboy.filter(lambda person: "Abitbol" in person.name).filter(age=50)
An attribute cannot be filtered twice:
>>> with sheraf.connection(): ... Cowboy.filter(age=30).filter(age=40) Traceback (most recent call last): ... sheraf.exceptions.InvalidFilterException: Some filter parameters appeared twice
Note
Filtering on indexed attributes is more performant than filtering on non-indexed attributes. See
index().
- get()[source]
If the
QuerySetcontains one, and only one item, this method returns the item. If theQuerySetcontains several objects, it raises aQuerySetUnpackException. If theQuerySetis empty, it raises aEmptyQuerySetUnpackException.>>> with sheraf.connection(): ... peter = Cowboy.create(name="Peter") ... steven = Cowboy.create(name="Steven") ... assert peter == Cowboy.filter(name="Peter").get() ... Cowboy.all().get() Traceback (most recent call last): ... sheraf.exceptions.TooManyValuesSetUnpackException: Trying to unpack a QuerySet with multiple elements <QuerySet model=Cowboy> >>> with sheraf.connection(): ... Cowboy.filter(age=30).get() Traceback (most recent call last): ... sheraf.exceptions.EmptyQuerySetUnpackException: Trying to unpack an empty QuerySet >>> with sheraf.connection(): ... Cowboy.filter(name="Unknown cowboy").get() Traceback (most recent call last): ... sheraf.exceptions.EmptyQuerySetUnpackException: Trying to unpack an empty QuerySet
- order(*args, **kwargs)[source]
Copies the current
QuerySetand adds more order to it.- Parameters:
args (
sheraf.ASCorsheraf.DESC) – There can be only one positionnal argument. Choose to iterate over ids in an ascending or a descending way.kwargs (A dictionary which keys must be valid attributes of the model iterated, and the values must be
sheraf.ASCorsheraf.DESC) – Further parameters will set an order on the matching model attributes.
- Returns:
A copy of the current
QuerySetwith refined order.- Return type:
The default order is the ascending model ids.
>>> with sheraf.connection(commit=True): ... peter = Cowboy.create(name="Peter", age=35) ... steven = Cowboy.create(name="Steven", age=35) ... george = Cowboy.create(name="George", age=50) ... >>> with sheraf.connection(): ... assert [peter, steven, george] == Cowboy.all() ... assert [peter, steven, george] == Cowboy.all().order(sheraf.ASC) ... assert [george, steven, peter] == Cowboy.all().order(sheraf.DESC) ... ... assert [george, peter, steven] == Cowboy.all().order(name=sheraf.ASC) ... assert [steven, peter, george] == Cowboy.all().order(name=sheraf.DESC)
Several order parameters can be passed, either as arguments of the function, or by calling
order()calls.>>> with sheraf.connection(): ... assert [george, peter, steven] == Cowboy.all().order(age=sheraf.DESC, name=sheraf.ASC)
- search(**kwargs)[source]
Refine a copy of the current
QuerySetwith further tests.This method is very similar to
filter()except the values it takes are transformed with the same way values are transformed at indexation. TODO: pas très clairFor instance, if an attribute indexes its values with a lowercase search_func, the
search()attributes will go through the same search_func. Hence it allows to pass uppercase filter values, whilefilter()does not allow this.>>> class MyCustomModel(sheraf.Model): ... table = "my_custom_model" ... my_attribute = sheraf.SimpleAttribute().index( ... index_keys_func=lambda string: {string.lower()} ... ) ... >>> with sheraf.connection(commit=True): ... m = MyCustomModel.create(my_attribute="FOO") ... >>> with sheraf.connection(): ... assert [m] == MyCustomModel.search(my_attribute="foo") ... assert [m] == MyCustomModel.filter(my_attribute="foo") ... ... assert [m] == MyCustomModel.search(my_attribute="FOO") ... assert [] == MyCustomModel.filter(my_attribute="FOO")