diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-04-24 15:49:52 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-04-24 15:49:52 -0400 |
| commit | 59ce77ca93bc3a0af054fbead17e927172047165 (patch) | |
| tree | 72467348efaa991d1dbad4f55905629ecc26f5e7 /lib/sqlalchemy/dialects/sqlite/base.py | |
| parent | d969d3a54a8f5423ac7769c5a3a641f46935a6d2 (diff) | |
| parent | 55b4295e39454430211a3c30cb8303a58a024f28 (diff) | |
| download | sqlalchemy-59ce77ca93bc3a0af054fbead17e927172047165.tar.gz | |
- [feature] the SQLite date and time types
have been overhauled to support a more open
ended format for input and output, using
name based format strings and regexps. A
new argument "microseconds" also provides
the option to omit the "microseconds"
portion of timestamps. Thanks to
Nathan Wright for the work and tests on
this. [ticket:2363]
Diffstat (limited to 'lib/sqlalchemy/dialects/sqlite/base.py')
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 128 |
1 files changed, 85 insertions, 43 deletions
diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index b9cd783be..9582db8f8 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -83,10 +83,7 @@ class DATETIME(_DateTimeMixin, sqltypes.DateTime): The default string storage format is:: - "%04d-%02d-%02d %02d:%02d:%02d.%06d" % (value.year, - value.month, value.day, - value.hour, value.minute, - value.second, value.microsecond) + "%(year)04d-%(month)02d-%(day)02d %(hour)02d:%(min)02d:%(second)02d.%(microsecond)06d" e.g.:: @@ -99,22 +96,38 @@ class DATETIME(_DateTimeMixin, sqltypes.DateTime): from sqlalchemy.dialects.sqlite import DATETIME dt = DATETIME( - storage_format="%04d/%02d/%02d %02d-%02d-%02d-%06d", - regexp=re.compile("(\d+)/(\d+)/(\d+) (\d+)-(\d+)-(\d+)(?:-(\d+))?") + storage_format="%(year)04d/%(month)02d/%(day)02d %(hour)02d:%(min)02d:%(second)02d", + regexp=re.compile("(\d+)/(\d+)/(\d+) (\d+)-(\d+)-(\d+)") ) :param storage_format: format string which will be applied to the - tuple ``(value.year, value.month, value.day, value.hour, - value.minute, value.second, value.microsecond)``, given a - Python datetime.datetime() object. + dict with keys year, month, day, hour, minute, second, and microsecond. :param regexp: regular expression which will be applied to - incoming result rows. The resulting match object is applied to - the Python datetime() constructor via ``*map(int, - match_obj.groups(0))``. + incoming result rows. If the regexp contains named groups, the + resulting match dict is applied to the Python datetime() constructor + as keyword arguments. Otherwise, if positional groups are used, the + the datetime() constructor is called with positional arguments via + ``*map(int, match_obj.groups(0))``. """ - _storage_format = "%04d-%02d-%02d %02d:%02d:%02d.%06d" + _storage_format = ( + "%(year)04d-%(month)02d-%(day)02d " + "%(hour)02d:%(minute)02d:%(second)02d.%(microsecond)06d" + ) + + def __init__(self, *args, **kwargs): + truncate_microseconds = kwargs.pop('truncate_microseconds', False) + super(DATETIME, self).__init__(*args, **kwargs) + if truncate_microseconds: + assert 'storage_format' not in kwargs, "You can specify only "\ + "one of truncate_microseconds or storage_format." + assert 'regexp' not in kwargs, "You can specify only one of "\ + "truncate_microseconds or regexp." + self._storage_format = ( + "%(year)04d-%(month)02d-%(day)02d " + "%(hour)02d:%(minute)02d:%(second)02d" + ) def bind_processor(self, dialect): datetime_datetime = datetime.datetime @@ -124,12 +137,25 @@ class DATETIME(_DateTimeMixin, sqltypes.DateTime): if value is None: return None elif isinstance(value, datetime_datetime): - return format % (value.year, value.month, value.day, - value.hour, value.minute, value.second, - value.microsecond) + return format % { + 'year': value.year, + 'month': value.month, + 'day': value.day, + 'hour': value.hour, + 'minute': value.minute, + 'second': value.second, + 'microsecond': value.microsecond, + } elif isinstance(value, datetime_date): - return format % (value.year, value.month, value.day, - 0, 0, 0, 0) + return format % { + 'year': value.year, + 'month': value.month, + 'day': value.day, + 'hour': 0, + 'minute': 0, + 'second': 0, + 'microsecond': 0, + } else: raise TypeError("SQLite DateTime type only accepts Python " "datetime and date objects as input.") @@ -147,7 +173,7 @@ class DATE(_DateTimeMixin, sqltypes.Date): The default string storage format is:: - "%04d-%02d-%02d" % (value.year, value.month, value.day) + "%(year)04d-%(month)02d-%(day)02d" e.g.:: @@ -160,22 +186,22 @@ class DATE(_DateTimeMixin, sqltypes.Date): from sqlalchemy.dialects.sqlite import DATE d = DATE( - storage_format="%02d/%02d/%02d", - regexp=re.compile("(\d+)/(\d+)/(\d+)") + storage_format="%(month)02d/%(day)02d/%(year)04d", + regexp=re.compile("(?P<month>\d+)/(?P<day>\d+)/(?P<year>\d+)") ) :param storage_format: format string which will be applied to the - tuple ``(value.year, value.month, value.day)``, - given a Python datetime.date() object. + dict with keys year, month, and day. :param regexp: regular expression which will be applied to - incoming result rows. The resulting match object is applied to - the Python date() constructor via ``*map(int, - match_obj.groups(0))``. - + incoming result rows. If the regexp contains named groups, the + resulting match dict is applied to the Python date() constructor + as keyword arguments. Otherwise, if positional groups are used, the + the date() constructor is called with positional arguments via + ``*map(int, match_obj.groups(0))``. """ - _storage_format = "%04d-%02d-%02d" + _storage_format = "%(year)04d-%(month)02d-%(day)02d" def bind_processor(self, dialect): datetime_date = datetime.date @@ -184,7 +210,11 @@ class DATE(_DateTimeMixin, sqltypes.Date): if value is None: return None elif isinstance(value, datetime_date): - return format % (value.year, value.month, value.day) + return format % { + 'year': value.year, + 'month': value.month, + 'day': value.day, + } else: raise TypeError("SQLite Date type only accepts Python " "date objects as input.") @@ -202,9 +232,7 @@ class TIME(_DateTimeMixin, sqltypes.Time): The default string storage format is:: - "%02d:%02d:%02d.%06d" % (value.hour, value.minute, - value.second, - value.microsecond) + "%(hour)02d:%(minute)02d:%(second)02d.%(microsecond)06d" e.g.:: @@ -217,22 +245,32 @@ class TIME(_DateTimeMixin, sqltypes.Time): from sqlalchemy.dialects.sqlite import TIME t = TIME( - storage_format="%02d-%02d-%02d-%06d", + storage_format="%(hour)02d-%(minute)02d-%(second)02d-%(microsecond)06d", regexp=re.compile("(\d+)-(\d+)-(\d+)-(?:-(\d+))?") ) - :param storage_format: format string which will be applied - to the tuple ``(value.hour, value.minute, value.second, - value.microsecond)``, given a Python datetime.time() object. + :param storage_format: format string which will be applied to the + dict with keys hour, minute, second, and microsecond. :param regexp: regular expression which will be applied to - incoming result rows. The resulting match object is applied to - the Python time() constructor via ``*map(int, - match_obj.groups(0))``. - + incoming result rows. If the regexp contains named groups, the + resulting match dict is applied to the Python time() constructor + as keyword arguments. Otherwise, if positional groups are used, the + the time() constructor is called with positional arguments via + ``*map(int, match_obj.groups(0))``. """ - _storage_format = "%02d:%02d:%02d.%06d" + _storage_format = "%(hour)02d:%(minute)02d:%(second)02d.%(microsecond)06d" + + def __init__(self, *args, **kwargs): + truncate_microseconds = kwargs.pop('truncate_microseconds', False) + super(TIME, self).__init__(*args, **kwargs) + if truncate_microseconds: + assert 'storage_format' not in kwargs, "You can specify only "\ + "one of truncate_microseconds or storage_format." + assert 'regexp' not in kwargs, "You can specify only one of "\ + "truncate_microseconds or regexp." + self._storage_format = "%(hour)02d:%(minute)02d:%(second)02d" def bind_processor(self, dialect): datetime_time = datetime.time @@ -241,8 +279,12 @@ class TIME(_DateTimeMixin, sqltypes.Time): if value is None: return None elif isinstance(value, datetime_time): - return format % (value.hour, value.minute, value.second, - value.microsecond) + return format % { + 'hour': value.hour, + 'minute': value.minute, + 'second': value.second, + 'microsecond': value.microsecond, + } else: raise TypeError("SQLite Time type only accepts Python " "time objects as input.") |
