Implemented QuerySet.datetimes on MySQL.
This commit is contained in:
parent
22d52681d3
commit
68ab511a4f
|
@ -30,3 +30,6 @@ class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler):
|
||||||
|
|
||||||
class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler):
|
class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class SQLDateTimeCompiler(compiler.SQLDateTimeCompiler, GeoSQLCompiler):
|
||||||
|
pass
|
||||||
|
|
|
@ -30,6 +30,7 @@ if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and
|
||||||
from MySQLdb.converters import conversions, Thing2Literal
|
from MySQLdb.converters import conversions, Thing2Literal
|
||||||
from MySQLdb.constants import FIELD_TYPE, CLIENT
|
from MySQLdb.constants import FIELD_TYPE, CLIENT
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.db import utils
|
from django.db import utils
|
||||||
from django.db.backends import *
|
from django.db.backends import *
|
||||||
from django.db.backends.signals import connection_created
|
from django.db.backends.signals import connection_created
|
||||||
|
@ -193,6 +194,12 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
"Confirm support for introspected foreign keys"
|
"Confirm support for introspected foreign keys"
|
||||||
return self._mysql_storage_engine != 'MyISAM'
|
return self._mysql_storage_engine != 'MyISAM'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def has_zoneinfo_database(self):
|
||||||
|
cursor = self.connection.cursor()
|
||||||
|
cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1")
|
||||||
|
return cursor.fetchone() is not None
|
||||||
|
|
||||||
class DatabaseOperations(BaseDatabaseOperations):
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
compiler_module = "django.db.backends.mysql.compiler"
|
compiler_module = "django.db.backends.mysql.compiler"
|
||||||
|
|
||||||
|
@ -218,6 +225,32 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
|
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
|
||||||
return sql
|
return sql
|
||||||
|
|
||||||
|
def datetime_extract_sql(self, lookup_type, field_name):
|
||||||
|
if settings.USE_TZ:
|
||||||
|
field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
|
||||||
|
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
||||||
|
if lookup_type == 'week_day':
|
||||||
|
# DAYOFWEEK() returns an integer, 1-7, Sunday=1.
|
||||||
|
# Note: WEEKDAY() returns 0-6, Monday=0.
|
||||||
|
return "DAYOFWEEK(%s)" % field_name
|
||||||
|
else:
|
||||||
|
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
|
||||||
|
|
||||||
|
def datetime_trunc_sql(self, lookup_type, field_name):
|
||||||
|
if settings.USE_TZ:
|
||||||
|
field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
|
||||||
|
fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
|
||||||
|
format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
|
||||||
|
format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
|
||||||
|
try:
|
||||||
|
i = fields.index(lookup_type) + 1
|
||||||
|
except ValueError:
|
||||||
|
sql = field_name
|
||||||
|
else:
|
||||||
|
format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
|
||||||
|
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
|
||||||
|
return sql
|
||||||
|
|
||||||
def date_interval_sql(self, sql, connector, timedelta):
|
def date_interval_sql(self, sql, connector, timedelta):
|
||||||
return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector,
|
return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector,
|
||||||
timedelta.days, timedelta.seconds, timedelta.microseconds)
|
timedelta.days, timedelta.seconds, timedelta.microseconds)
|
||||||
|
@ -314,11 +347,10 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
# MySQL doesn't support microseconds
|
# MySQL doesn't support microseconds
|
||||||
return six.text_type(value.replace(microsecond=0))
|
return six.text_type(value.replace(microsecond=0))
|
||||||
|
|
||||||
def year_lookup_bounds(self, value):
|
def year_lookup_bounds_for_datetime_field(self, value):
|
||||||
# Again, no microseconds
|
# Again, no microseconds
|
||||||
first = '%s-01-01 00:00:00'
|
first, second = super(DatabaseOperations, self).year_lookup_bounds_for_datetime_field(value)
|
||||||
second = '%s-12-31 23:59:59.99'
|
return [first.replace(microsecond=0), second.replace(microsecond=0)]
|
||||||
return [first % value, second % value]
|
|
||||||
|
|
||||||
def max_name_length(self):
|
def max_name_length(self):
|
||||||
return 64
|
return 64
|
||||||
|
|
|
@ -31,3 +31,6 @@ class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
|
||||||
|
|
||||||
class SQLDateCompiler(compiler.SQLDateCompiler, SQLCompiler):
|
class SQLDateCompiler(compiler.SQLDateCompiler, SQLCompiler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class SQLDateTimeCompiler(compiler.SQLDateTimeCompiler, SQLCompiler):
|
||||||
|
pass
|
||||||
|
|
Loading…
Reference in New Issue