Add minimal to_char for date and datetime on SQLite

We support only date and datetime with common pattern between SQL and Python.

issue8464
review261761002
This commit is contained in:
Cédric Krier committed 2019-08-07 19:34:33 +02:00
1 parent 1f2256d545
commit f56c5be5ad
3 files changed
+72 -1

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Add partial TO_CHAR support for date and datetime on SQLite
* Setup default logging for WSGI app
* Add format argument to report format_date function
* Change expand attribute into a factor
+45
View File
@@ -140,6 +140,50 @@ def now():
_nows = WeakKeyDictionary()
def to_char(value, format):
try:
value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S.%f')
except ValueError:
try:
value = datetime.datetime.strptime(value, '%Y-%m-%d').date()
except ValueError:
pass
if isinstance(value, datetime.date):
# Convert SQL pattern into compatible Python
return value.strftime(format
.replace('%', '%%')
.replace('HH12', '%I')
.replace('HH24', '%H')
.replace('HH', '%I')
.replace('MI', '%M')
.replace('SS', '%S')
.replace('US', '%f')
.replace('AM', '%p')
.replace('A.M.', '%p')
.replace('PM', '%p')
.replace('P.M.', '%p')
.replace('am', '%p')
.replace('a.m.', '%p')
.replace('pm', '%p')
.replace('p.m.', '%p')
.replace('YYYY', '%Y')
.replace('YY', '%y')
.replace('Month', '%B')
.replace('Mon', '%b')
.replace('MM', '%m')
.replace('Day', '%A')
.replace('Dy', '%a')
.replace('DDD', '%j')
.replace('DD', '%d')
.replace('D', '%w')
.replace('TZ', '%Z')
)
elif isinstance(value, datetime.timedelta):
raise NotImplementedError
else:
raise NotImplementedError
class SQLiteSubstring(Function):
__slots__ = ()
_function = 'SUBSTR'
@@ -290,6 +334,7 @@ class Database(DatabaseInterface):
self._conn.create_function('date_trunc', 2, date_trunc)
self._conn.create_function('split_part', 3, split_part)
self._conn.create_function('position', 2, SQLitePosition.position)
self._conn.create_function('to_char', 2, to_char)
self._conn.create_function('overlay', 3, SQLiteOverlay.overlay)
self._conn.create_function('overlay', 4, SQLiteOverlay.overlay)
if sqlite.sqlite_version_info < (3, 3, 14):
+26 -1
View File
@@ -1,9 +1,10 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import datetime
import unittest
from sql import Select
from sql.functions import CurrentTimestamp
from sql.functions import CurrentTimestamp, ToChar
from trytond.tests.test_tryton import activate_module, with_transaction
from trytond.transaction import Transaction
@@ -59,6 +60,30 @@ class BackendTestCase(unittest.TestCase):
self.assertNotEqual(current, second)
@with_transaction()
def test_to_char_datetime(self):
"Test TO_CHAR with datetime"
now = datetime.datetime.now()
query = Select([ToChar(now, 'YYYYMMDD HH24:MI:SS.US')])
cursor = Transaction().connection.cursor()
cursor.execute(*query)
text, = cursor.fetchone()
self.assertEqual(text, now.strftime('%Y%m%d %H:%M:%S.%f'))
@with_transaction()
def test_to_char_date(self):
"Test TO_CHAR with date"
today = datetime.date.today()
query = Select([ToChar(today, 'YYYY-MM-DD')])
cursor = Transaction().connection.cursor()
cursor.execute(*query)
text, = cursor.fetchone()
self.assertEqual(text, today.strftime('%Y-%m-%d'))
def suite():
return unittest.TestLoader().loadTestsFromTestCase(BackendTestCase)