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:
1 parent
1f2256d545
commit
f56c5be5ad
3 files changed
+72
-1
No files matched your search
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
Reference in new issue
Block a user