summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/cyextension
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-04-03 13:44:57 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-04-03 14:47:52 -0400
commitccadbec82555c53eefa889160510f5af1e224709 (patch)
tree959b4309fcc26191ef791034bda76e6fda0d1bdb /lib/sqlalchemy/cyextension
parent1dffb7cedeb009ca6c532db558bd0588dd846957 (diff)
downloadsqlalchemy-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.pyx57
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, &microsecond)
- 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, &microsecond)
- if numparsed < 3:
- raise ValueError(
- "Couldn't parse time string: '%s'" % (value)
- )
- return time_new(hour, minute, second, microsecond, None)
cdef class DecimalResultProcessor: