mirror of https://github.com/django/django.git
Factored out database-specific date_trunc behavior into dbmod.get_date_trunc_sql(). Refs #46
git-svn-id: http://code.djangoproject.com/svn/django/trunk@161 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d4ddc06021
commit
b1c543d091
|
@ -29,5 +29,6 @@ dictfetchall = dbmod.dictfetchall
|
||||||
dictfetchall = dbmod.dictfetchall
|
dictfetchall = dbmod.dictfetchall
|
||||||
get_last_insert_id = dbmod.get_last_insert_id
|
get_last_insert_id = dbmod.get_last_insert_id
|
||||||
get_date_extract_sql = dbmod.get_date_extract_sql
|
get_date_extract_sql = dbmod.get_date_extract_sql
|
||||||
|
get_date_trunc_sql = dbmod.get_date_trunc_sql
|
||||||
OPERATOR_MAPPING = dbmod.OPERATOR_MAPPING
|
OPERATOR_MAPPING = dbmod.OPERATOR_MAPPING
|
||||||
DATA_TYPES = dbmod.DATA_TYPES
|
DATA_TYPES = dbmod.DATA_TYPES
|
||||||
|
|
|
@ -64,8 +64,21 @@ def get_last_insert_id(cursor, table_name, pk_name):
|
||||||
|
|
||||||
def get_date_extract_sql(lookup_type, table_name):
|
def get_date_extract_sql(lookup_type, table_name):
|
||||||
# lookup_type is 'year', 'month', 'day'
|
# lookup_type is 'year', 'month', 'day'
|
||||||
|
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
||||||
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), table_name)
|
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), table_name)
|
||||||
|
|
||||||
|
def get_date_trunc_sql(lookup_type, field_name):
|
||||||
|
# lookup_type is 'year', 'month', 'day'
|
||||||
|
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
||||||
|
# MySQL doesn't support DATE_TRUNC, so we fake it by subtracting intervals.
|
||||||
|
# If you know of a better way to do this, please file a Django ticket.
|
||||||
|
subtractions = ["interval (DATE_FORMAT(%s, '%%%%s')) second - interval (DATE_FORMAT(%s, '%%%%i')) minute - interval (DATE_FORMAT(%s, '%%%%H')) hour" % (field_name, field_name, field_name)]
|
||||||
|
if lookup_type in ('year', 'month'):
|
||||||
|
subtractions.append(" - interval (DATE_FORMAT(%s, '%%%%e')-1) day" % field_name)
|
||||||
|
if lookup_type == 'year':
|
||||||
|
subtractions.append(" - interval (DATE_FORMAT(%s, '%%%%m')-1) month" % field_name)
|
||||||
|
return "(%s - %s)" % (field_name, ''.join(subtractions))
|
||||||
|
|
||||||
OPERATOR_MAPPING = {
|
OPERATOR_MAPPING = {
|
||||||
'exact': '=',
|
'exact': '=',
|
||||||
'iexact': 'LIKE',
|
'iexact': 'LIKE',
|
||||||
|
|
|
@ -63,8 +63,14 @@ def get_last_insert_id(cursor, table_name, pk_name):
|
||||||
|
|
||||||
def get_date_extract_sql(lookup_type, table_name):
|
def get_date_extract_sql(lookup_type, table_name):
|
||||||
# lookup_type is 'year', 'month', 'day'
|
# lookup_type is 'year', 'month', 'day'
|
||||||
|
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
|
||||||
return "EXTRACT('%s' FROM %s)" % (lookup_type, table_name)
|
return "EXTRACT('%s' FROM %s)" % (lookup_type, table_name)
|
||||||
|
|
||||||
|
def get_date_trunc_sql(lookup_type, field_name):
|
||||||
|
# lookup_type is 'year', 'month', 'day'
|
||||||
|
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
|
||||||
|
return "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
|
||||||
|
|
||||||
# Register these custom typecasts, because Django expects dates/times to be
|
# Register these custom typecasts, because Django expects dates/times to be
|
||||||
# in Python's native (standard-library) datetime/time format, whereas psycopg
|
# in Python's native (standard-library) datetime/time format, whereas psycopg
|
||||||
# use mx.DateTime by default.
|
# use mx.DateTime by default.
|
||||||
|
|
|
@ -1264,6 +1264,7 @@ def function_get_latest(opts, klass, does_not_exist_exception, **kwargs):
|
||||||
return function_get_object(opts, klass, does_not_exist_exception, **kwargs)
|
return function_get_object(opts, klass, does_not_exist_exception, **kwargs)
|
||||||
|
|
||||||
def function_get_date_list(opts, field, *args, **kwargs):
|
def function_get_date_list(opts, field, *args, **kwargs):
|
||||||
|
from django.core.db.typecasts import typecast_timestamp
|
||||||
kind = args and args[0] or kwargs['kind']
|
kind = args and args[0] or kwargs['kind']
|
||||||
assert kind in ("month", "year", "day"), "'kind' must be one of 'year', 'month' or 'day'."
|
assert kind in ("month", "year", "day"), "'kind' must be one of 'year', 'month' or 'day'."
|
||||||
order = 'ASC'
|
order = 'ASC'
|
||||||
|
@ -1275,10 +1276,13 @@ def function_get_date_list(opts, field, *args, **kwargs):
|
||||||
if field.null:
|
if field.null:
|
||||||
kwargs.setdefault('where', []).append('%s.%s IS NOT NULL' % (opts.db_table, field.name))
|
kwargs.setdefault('where', []).append('%s.%s IS NOT NULL' % (opts.db_table, field.name))
|
||||||
select, sql, params = function_get_sql_clause(opts, **kwargs)
|
select, sql, params = function_get_sql_clause(opts, **kwargs)
|
||||||
sql = "SELECT DATE_TRUNC(%%s, %s.%s) %s GROUP BY 1 ORDER BY 1 %s" % (opts.db_table, field.name, sql, order)
|
sql = 'SELECT %s %s GROUP BY 1 ORDER BY 1' % (db.get_date_trunc_sql(kind, '%s.%s' % (opts.db_table, field.name)), sql)
|
||||||
cursor = db.db.cursor()
|
cursor = db.db.cursor()
|
||||||
cursor.execute(sql, [kind] + params)
|
cursor.execute(sql, params)
|
||||||
return [row[0] for row in cursor.fetchall()]
|
# We have to manually run typecast_timestamp(str()) on the results, because
|
||||||
|
# MySQL doesn't automatically cast the result of date functions as datetime
|
||||||
|
# objects -- MySQL returns the values as strings, instead.
|
||||||
|
return [typecast_timestamp(str(row[0])) for row in cursor.fetchall()]
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
# HELPER FUNCTIONS (MANIPULATORS) #
|
# HELPER FUNCTIONS (MANIPULATORS) #
|
||||||
|
|
Loading…
Reference in New Issue