diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-04-03 13:44:57 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-04-03 14:47:52 -0400 |
| commit | ccadbec82555c53eefa889160510f5af1e224709 (patch) | |
| tree | 959b4309fcc26191ef791034bda76e6fda0d1bdb /lib/sqlalchemy/cyextension | |
| parent | 1dffb7cedeb009ca6c532db558bd0588dd846957 (diff) | |
| download | sqlalchemy-ccadbec82555c53eefa889160510f5af1e224709.tar.gz | |
use .fromisoformat() for sqlite datetime, date, time parsing
SQLite datetime, date, and time datatypes now use Python standard lib
``fromisoformat()`` methods in order to parse incoming datetime, date, and
time string values. This improves performance vs. the previous regular
expression-based approach, and also automatically accommodates for datetime
and time formats that contain either a six-digit "microseconds" format or a
three-digit "milliseconds" format.
Fixes: #7029
Change-Id: I67aab4fe5ee3055e5996050cf4564981413cc221
Diffstat (limited to 'lib/sqlalchemy/cyextension')
| -rw-r--r-- | lib/sqlalchemy/cyextension/processors.pyx | 57 |
1 files changed, 14 insertions, 43 deletions
diff --git a/lib/sqlalchemy/cyextension/processors.pyx b/lib/sqlalchemy/cyextension/processors.pyx index 9f23e73b1..b0ad865c5 100644 --- a/lib/sqlalchemy/cyextension/processors.pyx +++ b/lib/sqlalchemy/cyextension/processors.pyx @@ -1,7 +1,9 @@ import datetime +from datetime import datetime as datetime_cls +from datetime import time as time_cls +from datetime import date as date_cls import re -from cpython.datetime cimport date_new, datetime_new, import_datetime, time_new from cpython.object cimport PyObject_Str from cpython.unicode cimport PyUnicode_AsASCIIString, PyUnicode_Check, PyUnicode_Decode from libc.stdio cimport sscanf @@ -27,53 +29,22 @@ cdef inline bytes to_bytes(object value, str type_name): "- value is not a string." ) from e -import_datetime() # required to call datetime_new/date_new/time_new - def str_to_datetime(value): - if value is None: - return None - cdef int numparsed - cdef unsigned int year, month, day, hour, minute, second, microsecond = 0 - cdef bytes value_b = to_bytes(value, 'datetime') - cdef const char * string = value_b - - numparsed = sscanf(string, "%4u-%2u-%2u %2u:%2u:%2u.%6u", - &year, &month, &day, &hour, &minute, &second, µsecond) - if numparsed < 6: - raise ValueError( - "Couldn't parse datetime string: '%s'" % (value) - ) - return datetime_new(year, month, day, hour, minute, second, microsecond, None) + if value is not None: + value = datetime_cls.fromisoformat(value) + return value -def str_to_date(value): - if value is None: - return None - cdef int numparsed - cdef unsigned int year, month, day - cdef bytes value_b = to_bytes(value, 'date') - cdef const char * string = value_b +def str_to_time(value): + if value is not None: + value = time_cls.fromisoformat(value) + return value - numparsed = sscanf(string, "%4u-%2u-%2u", &year, &month, &day) - if numparsed != 3: - raise ValueError( - "Couldn't parse date string: '%s'" % (value) - ) - return date_new(year, month, day) -def str_to_time(value): - if value is None: - return None - cdef int numparsed - cdef unsigned int hour, minute, second, microsecond = 0 - cdef bytes value_b = to_bytes(value, 'time') - cdef const char * string = value_b +def str_to_date(value): + if value is not None: + value = date_cls.fromisoformat(value) + return value - numparsed = sscanf(string, "%2u:%2u:%2u.%6u", &hour, &minute, &second, µsecond) - if numparsed < 3: - raise ValueError( - "Couldn't parse time string: '%s'" % (value) - ) - return time_new(hour, minute, second, microsecond, None) cdef class DecimalResultProcessor: |
