From 1460d4c85e3c64c207f3079d6263196bc3da3789 Mon Sep 17 00:00:00 2001 From: nikepan Date: Mon, 27 Mar 2017 16:30:38 +0300 Subject: [PATCH 1/5] blank datetime fix --- src/infi/clickhouse_orm/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infi/clickhouse_orm/fields.py b/src/infi/clickhouse_orm/fields.py index 3fa49ec..b022652 100644 --- a/src/infi/clickhouse_orm/fields.py +++ b/src/infi/clickhouse_orm/fields.py @@ -137,7 +137,7 @@ class DateTimeField(Field): raise ValueError('Invalid value for %s - %r' % (self.__class__.__name__, value)) def to_db_string(self, value, quote=True): - return escape(timegm(value.utctimetuple()), quote) + return escape(timegm(value.utctimetuple()) or '0000000000', quote) class BaseIntField(Field): From 9baa863d1fe865478f6e18b1ba63cd148488f8f9 Mon Sep 17 00:00:00 2001 From: nikepan Date: Mon, 27 Mar 2017 16:51:34 +0300 Subject: [PATCH 2/5] blank datetime better fix --- src/infi/clickhouse_orm/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infi/clickhouse_orm/fields.py b/src/infi/clickhouse_orm/fields.py index b022652..0a17870 100644 --- a/src/infi/clickhouse_orm/fields.py +++ b/src/infi/clickhouse_orm/fields.py @@ -137,7 +137,7 @@ class DateTimeField(Field): raise ValueError('Invalid value for %s - %r' % (self.__class__.__name__, value)) def to_db_string(self, value, quote=True): - return escape(timegm(value.utctimetuple()) or '0000000000', quote) + return escape(('0000000000' + str(timegm(value.utctimetuple())))[-10:], quote) class BaseIntField(Field): From e5222ffcb07b41a7bdb532a613b932da327ee10d Mon Sep 17 00:00:00 2001 From: nikepan Date: Mon, 27 Mar 2017 17:03:13 +0300 Subject: [PATCH 3/5] blank datetime fix improve --- src/infi/clickhouse_orm/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infi/clickhouse_orm/fields.py b/src/infi/clickhouse_orm/fields.py index 0a17870..166f1ff 100644 --- a/src/infi/clickhouse_orm/fields.py +++ b/src/infi/clickhouse_orm/fields.py @@ -137,7 +137,7 @@ class DateTimeField(Field): raise ValueError('Invalid value for %s - %r' % (self.__class__.__name__, value)) def to_db_string(self, value, quote=True): - return escape(('0000000000' + str(timegm(value.utctimetuple())))[-10:], quote) + return escape('%010d' % (timegm(value.utctimetuple())), quote) class BaseIntField(Field): From b2a5482a65cb44b3dc4f6b4ea070e441e19cb6d9 Mon Sep 17 00:00:00 2001 From: nikepan Date: Mon, 27 Mar 2017 17:07:10 +0300 Subject: [PATCH 4/5] blank datetime fix beauty --- src/infi/clickhouse_orm/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infi/clickhouse_orm/fields.py b/src/infi/clickhouse_orm/fields.py index 166f1ff..f7773e9 100644 --- a/src/infi/clickhouse_orm/fields.py +++ b/src/infi/clickhouse_orm/fields.py @@ -137,7 +137,7 @@ class DateTimeField(Field): raise ValueError('Invalid value for %s - %r' % (self.__class__.__name__, value)) def to_db_string(self, value, quote=True): - return escape('%010d' % (timegm(value.utctimetuple())), quote) + return escape('%010d' % timegm(value.utctimetuple()), quote) class BaseIntField(Field): From 015a4512e79626fbd8828dc97bbba9429e518da6 Mon Sep 17 00:00:00 2001 From: Itai Shirav Date: Tue, 4 Apr 2017 12:41:18 +0300 Subject: [PATCH 5/5] Fix datetime tests --- README.rst | 1 - src/infi/clickhouse_orm/fields.py | 6 ++++++ tests/test_simple_fields.py | 23 ++++++----------------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/README.rst b/README.rst index 9db0ab1..e03fabb 100644 --- a/README.rst +++ b/README.rst @@ -425,7 +425,6 @@ After cloning the project, run the following commands:: To run the tests, ensure that the ClickHouse server is running on http://localhost:8123/ (this is the default), and run:: bin/nosetests -======= To see test coverage information run:: diff --git a/src/infi/clickhouse_orm/fields.py b/src/infi/clickhouse_orm/fields.py index f7773e9..915ebee 100644 --- a/src/infi/clickhouse_orm/fields.py +++ b/src/infi/clickhouse_orm/fields.py @@ -132,6 +132,12 @@ class DateTimeField(Field): if isinstance(value, string_types): if value == '0000-00-00 00:00:00': return self.class_default + if len(value) == 10: + try: + value = int(value) + return datetime.datetime.utcfromtimestamp(value).replace(tzinfo=pytz.utc) + except ValueError: + pass dt = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S') return timezone_in_use.localize(dt).astimezone(pytz.utc) raise ValueError('Invalid value for %s - %r' % (self.__class__.__name__, value)) diff --git a/tests/test_simple_fields.py b/tests/test_simple_fields.py index 2d1f2ab..645d9ed 100644 --- a/tests/test_simple_fields.py +++ b/tests/test_simple_fields.py @@ -6,32 +6,17 @@ import pytz class SimpleFieldsTest(unittest.TestCase): - def test_date_field(self): - f = DateField() - # Valid values - for value in (date(1970, 1, 1), datetime(1970, 1, 1), '1970-01-01', '0000-00-00', 0): - self.assertEquals(f.to_python(value, pytz.utc), date(1970, 1, 1)) - # Invalid values - for value in ('nope', '21/7/1999', 0.5): - with self.assertRaises(ValueError): - f.to_python(value, pytz.utc) - # Range check - for value in (date(1900, 1, 1), date(2900, 1, 1)): - with self.assertRaises(ValueError): - f.validate(value) - def test_datetime_field(self): f = DateTimeField() epoch = datetime(1970, 1, 1, tzinfo=pytz.utc) # Valid values for value in (date(1970, 1, 1), datetime(1970, 1, 1), epoch, epoch.astimezone(pytz.timezone('US/Eastern')), epoch.astimezone(pytz.timezone('Asia/Jerusalem')), - '1970-01-01 00:00:00', '0000-00-00 00:00:00', 0): + '1970-01-01 00:00:00', '1970-01-17 00:00:17', '0000-00-00 00:00:00', 0): dt = f.to_python(value, pytz.utc) self.assertEquals(dt.tzinfo, pytz.utc) - self.assertEquals(dt, epoch) # Verify that conversion to and from db string does not change value - dt2 = f.to_python(int(f.to_db_string(dt)), pytz.utc) + dt2 = f.to_python(f.to_db_string(dt, quote=False), pytz.utc) self.assertEquals(dt, dt2) # Invalid values for value in ('nope', '21/7/1999', 0.5): @@ -52,6 +37,10 @@ class SimpleFieldsTest(unittest.TestCase): for value in ('nope', '21/7/1999', 0.5): with self.assertRaises(ValueError): f.to_python(value, pytz.utc) + # Range check + for value in (date(1900, 1, 1), date(2900, 1, 1)): + with self.assertRaises(ValueError): + f.validate(value) def test_date_field_timezone(self): # Verify that conversion of timezone-aware datetime is correct