Description
The discussion in #397 is about using filtering and querysets with point-in-time queries. The current as_of
implementation returns a instance generator so it can only be used to make a single query and obtain the result. The documentation states that it must return an iterable, so it does not have to be a generator. As a queryset, no tests needed to change to handle it.
HistoricalQuerySet is now returned from queries on history. This is used internally by as_of queries to prune results to the latest of each primary key, and to convert to instances.
The resulting queryset from as_of can be further filtered; any use of pk
will be converted to the original model's primary key if the queryset is returning instances.
Example (from unit tests):
def test_as_of(self):
"""Demonstrates how as_of works now that it returns a QuerySet."""
t0 = datetime.now()
document1 = RankedDocument.objects.create(rank=42)
document2 = RankedDocument.objects.create(rank=84)
t1 = datetime.now()
document2.rank = 51
document2.save()
document1.delete()
t2 = datetime.now()
# nothing exists at t0
queryset = RankedDocument.history.as_of(t0)
self.assertEqual(queryset.count(), 0)
# at t1, two records exist
queryset = RankedDocument.history.as_of(t1)
self.assertEqual(queryset.count(), 2)
self.assertEqual(queryset.filter(rank__gte=75).count(), 1)
ids = set([item["id"] for item in queryset.values("id")])
self.assertEqual(ids, {document1.id, document2.id})
# at t2 we have one record left
queryset = RankedDocument.history.as_of(t2)
self.assertEqual(queryset.count(), 1)
self.assertEqual(queryset.filter(rank__gte=75).count(), 0)
Related Issues
#118
#229
#354
This closes #397
#715
#758
This closes #803
Motivation and Context
A long-standing issue that kept me from using the library effectively.
How Has This Been Tested?
Tests were added, all tests pass. Existing tests did not have to change. Additionally, my company has been using this in production for over a month.
Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
Checklist:
- [X] I have run the
make format
command to format my code
- [X] My change requires a change to the documentation.
- [X] I have updated the documentation accordingly.
- [X] I have read the CONTRIBUTING document.
- [X] I have added tests to cover my changes.
- [X] I have added my name and/or github handle to
AUTHORS.rst
- [X] I have added my change to
CHANGES.rst
- [X] All new and existing tests passed.