Comparing unix timestamp with date in Django ORM - django

I am trying to fetch all records from a table on a particular date.
My url.py code is :
url(r'^jobs/date/?P<date>.*',RunningJobsListApiView.as_view()),
Here is the code of my view to get all the records from the table.
class RunningJobsListApiView(generics.ListAPIView):
queryset = LinuxJobTable.objects.annotate(status=Case(When(state=3, then=Value('Completed')),When(state=5, then=Value('Failed')),When(state=1, then=Value('Running')),default=Value('Unknown'),output_field=CharField(),),)
serializer_class = JobInfoSerializer
Now, I want to filter the jobs for the particular date in url. But In my database date is in UNIX timestamp format(ie.1530773247).
How can I compare DateFormat(mm-dd-yyyy) with UNIX timestamp format saved in DB?

To get a UNIX timestamp from a string date representation, you first need to convert the string to a Python datetime with strptime(), and then call the timestamp() method on it. But since a single day comprises a range of timestamps, you need to do a range query between the start of the target day and the start of the next day.
Something like:
from datetime import datetime, timedelta
target_day = datetime.strptime(date, "%m-%d-%Y")
next_day = target_day + timedelta(days=1)
queryset = LinuxJobTable.objects.filter(timestamp__range=(
int(target_day.timestamp()),
int(next_day.timestamp()) - 1 # since range is inclusive
))

Related

Filter data for a given day (timezone aware datetime) from postgres directly

I want to filter all data for the following day (which is timezone aware).
Assumptions:
server data is in a specific timezone
client query is coming from different timezone
My current approach is:
date = received_date_timezone_aware # any time of that day
lower = date.replace(hour=0,minute=0,second=0)
upper = lower + datetime.timedelta(day=1)
data = Model.objects.filter(date__gte=lower, date__lt=upper)
Question
Is there a direct solution to this using django orm or raw query?
Note: I wanted to know if there is a better way which can save me a few lines of code of manipulating the datetime myself
No, there isn't. However what you're doing isn't the best way to do it either as using replace can result in some oddities with day lights savings. I'd recommend using lower = received_date_timezone_aware.date().
This assumes Model.date is a DateField. If it's a datetime, then do this:
from datetime import time, datetime
def min_datetime(date: datetime, tz):
"""Get the min datetime of the given datetime and timezone.
:return datetime: Minimum datetime of the given date.
"""
return tz.localize(
datetime.combine(date.astimezone(tz).date(), time.min))
def max_datetime(date: datetime, tz):
"""Get the max datetime of the given datetime and timezone.
:return datetime: Maximum datetime of the given date.
"""
return tz.localize(
datetime.combine(date.astimezone(tz).date(), time.max))
Model.objects.filter(date__range=(min_datetime(value, tz), max_datetime(value, tz)))

Using Django ORM to retrieve recent rows

In SQL, if I wanted to query a table for data from the most recent 10 minutes (regardless of timezones and such), I'd simply do (using postgresql parlance):
select * from table where creation_time > now() - interval'10 mins';
Is there an equivalent way to do something like this using the Django ORM, disregarding what timezone settings one has set for the app? Would be great to get an illustrative example here.
Try this:-
Data within 10 minutes :-
from datetime import datetime, timedelta
time_threshold = datetime.now() - timedelta(minutes=10)
results = Table.objects.filter(createdOn__lte=time_threshold)
Last 10 rows based on createdOn value:-
recentData = Table.objects.all().order_by('-createdOn')[:10]
Last 10 rows if you don't have createdOn column to filter:-
recentData = Table.objects.all().order_by('-id')[:10]

Filter two dates in one query django/python

Is there a way I can filter two datefield columns from a table on the same query?
Example:
I have date_ots and date_lta I need to filter and get the result from today + 4 days on both columns.
Thanks for your attention,
Alex
If you would like exact timing (hours, min, sec), you can do:
from datetime import timedelta
four_days_from_now = timezone.now() + timedelta(days=4)
query = Model.objects.filter(date_ots=four_days_from_now, date_lta=four_days_from_now)
If you only want the date 4 days from now (at any time), you can do:
from datetime import timedelta
four_days_from_now = timezone.now().date() + timedelta(days=4)
query = Model.objects.filter(date_ots=four_days_from_now, date_lta=four_days_from_now)

Group objects by dates

clicks = SellerClick.objects.extra({'date' : "date(timestamp)"}).values('date').annotate(count=Count('timestamp'))
The model has a datetime field called timestamp that was are using. I first, convert the datetime field to just a date field. Then the rest is guessing. I need to group by, and then count how many objects are of each date.
So the desired result would be a date, then a count, based on how many objects have that date in the timestamp field.
I prefer to use annotate over extra
from django.db.models.expressions import RawSQL
SellerClick.objects.annotate(
date=RawSQL('date(date_joined)',[]),
).values('date').annotate(count=Count('date')))
You've got everything but an initial queryset there. The extra sql you're passing doesn't include a select so you need to give it something to act on.
clicks = SellerClick.objects.all()
.extra({'date' : "date(timestamp)"})
.values('date')
.annotate(count=Count('timestamp'))
Ref: StackOverflow: Count number of records by date in Django

Django queryset aggregate by time interval

Hi I am writing a Django view which ouputs data for graphing on the client side (High Charts). The data is climate data with a given parameter recorded once per day.
My query is this:
format = '%Y-%m-%d'
sd = datetime.datetime.strptime(startdate, format)
ed = datetime.datetime.strptime(enddate, format)
data = Climate.objects.filter(recorded_on__range = (sd, ed)).order_by('recorded_on')
Now, as the range is increased the dataset obviously gets larger and this does not present well on the graph (aside from slowing things down considerably).
Is there an way to group my data as averages in time periods - specifically average for each month or average for each year?
I realize this could be done in SQL as mentioned here: django aggregation to lower resolution using grouping by a date range
But I would like to know if there is a handy way in Django itself.
Or is it perhaps better to modify the db directly and use a script to populate month and year fields from the timestamp?
Any help much appreciated.
Have you tried using django-qsstats-magic (https://github.com/kmike/django-qsstats-magic)?
It makes things very easy for charting, here is a timeseries example from their docs:
from django.contrib.auth.models import User
import datetime, qsstats
qs = User.objects.all()
qss = qsstats.QuerySetStats(qs, 'date_joined')
today = datetime.date.today()
seven_days_ago = today - datetime.timedelta(days=7)
time_series = qss.time_series(seven_days_ago, today)
print 'New users in the last 7 days: %s' % [t[1] for t in time_series]