I have a Django application which generates some graphs with Google Visualization API (Google charts) based on django aggregate querysets. The Google Charts API expects the data to be in correct format to plot generate the graph correctly (ie. dates need to be of javascript type Date, not integer or float).
Say I want to create an aggregate for my model Posts to display for example total number of records by a particular user per year. My code would look something like this:
qset = Post.objects.filter(user__id=1).extra(select={"year": "date_part('year', cdt)"}\
.values("year").annotate(num_records=Count("id")).order_by()
This work quite nice, except that the date_part() postgresql function which is used to extract the year from a timestampz field returns as a float, not an int, which in case mess up my chart data.
Running a similar query from psql returns a integer, which is what I expects.
select date_part('year', cdt) from public.core_post where id=6543;
date_part
-----------
2011
(1 row)
Again, running a small python program using the psycopg2 library gives me the same problem:
import psycopg2
def main():
conn_string = "host='localhost' dbname='mydb' user='username' password='secret'"
conn = psycopg2.connect(conn_string)
cursor = conn.cursor()
sql = "select date_part('year', cdt) from public.core_post where id=6543;"
cursor.execute(sql)
for rec in cursor.fetchone():
print type(rec), rec
if __name__ == '__main__':
main()
<type 'float'> 2011.0
[Finished in 0.1s]
Anybody got a clue why, or if it’s fixable?
(I can of course write a function which fix this before passing data to my graph library, but I’d rather be able to pass in the queryset (because that’s how I’ve written my graph lib).)
Okay, embarrassing.
Just re-read the PostgreSQL documentation about date_part which clearly says:
I’ll just accept this as an answer, and leave it for future reference.
Solved by casting the result of
date_part()to int.