Skip to content

Commit

Permalink
Add support for datetime.
Browse files Browse the repository at this point in the history
  • Loading branch information
elektito committed Jan 26, 2018
1 parent c5f8a22 commit 4c8bb1b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
5 changes: 3 additions & 2 deletions subconscious/column.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3

from datetime import datetime
from enum import EnumMeta


Expand All @@ -18,8 +19,8 @@ def __init__(self, type=str, primary_key=None, composite_key=None, index=None,
You can't have both a primary_key and composite_key in the same model.
index is whether you want this column indexed or not for faster retrieval.
"""
if type not in (str, int):
# TODO: support for other field types (datetime, uuid, etc)
if type not in (str, int, datetime):
# TODO: support for other field types (uuid, etc)
err_msg = 'Bad Field Type: {}'.format(type)
raise InvalidColumnDefinition(err_msg)

Expand Down
12 changes: 11 additions & 1 deletion subconscious/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import inspect
import logging
import uuid
from datetime import datetime

from .column import Column
from .query import Query
Expand All @@ -12,6 +13,7 @@

VALUE_ID_SEPARATOR = '\x00'
MODEL_NAME_ID_SEPARATOR = ':'
DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S.%f'


# Exceptions
Expand Down Expand Up @@ -210,7 +212,11 @@ async def save(self, db):

# we have to delete the old index key
stale_object = await self.__class__.load(db, identifier=self.identifier())
success = await db.hmset_dict(self.redis_key(), self.__dict__.copy())
d = {
k: (v.strftime(DATETIME_FORMAT) if isinstance(v, datetime) else v)
for k, v in self.__dict__.items()
}
success = await db.hmset_dict(self.redis_key(), d)
await self.save_index(db, stale_object=stale_object)
return success

Expand All @@ -234,6 +240,8 @@ async def load(cls, db, identifier=None, redis_key=None):
column = getattr(cls, key, False)
if not column or (column.field_type == str):
kwargs[key] = value
elif column.field_type == datetime:
kwargs[key] = datetime.strptime(value, DATETIME_FORMAT)
else:
kwargs[key] = column.field_type(value)
kwargs['loading'] = True
Expand Down Expand Up @@ -304,6 +312,8 @@ async def _get_ids_filter_by(cls, db, order_by=None, **kwargs):
v = cls._columns_map[k]
if isinstance(v, (list, tuple)):
values = [str(x) for x in v]
elif isinstance(v, datetime):
values = (v.strftime(DATETIME_FORMAT),)
else:
values = (str(v),)
temp_set = set()
Expand Down
8 changes: 7 additions & 1 deletion tests/test_all.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from subconscious.model import RedisModel, Column, InvalidQuery
from uuid import uuid1
from datetime import datetime
from .base import BaseTestCase
import enum

Expand All @@ -14,6 +15,7 @@ class TestUser(RedisModel):
age = Column(index=True, type=int,)
locale = Column(index=True, type=int, required=False)
status = Column(type=str, enum=StatusEnum)
birth_date = Column(type=datetime, required=False)


class TestAll(BaseTestCase):
Expand All @@ -26,7 +28,8 @@ def setUp(self):
self.assertTrue(ret)

user_id = str(uuid1())
user1 = TestUser(id=user_id, name='ZTest name', age=53)
bdate = datetime(1854, 1, 6, 14, 35, 19)
user1 = TestUser(id=user_id, name='ZTest name', age=53, birth_date=bdate)
ret = self.loop.run_until_complete(user1.save(self.db))
self.assertTrue(ret)

Expand All @@ -41,6 +44,9 @@ async def _test_all():
self.assertEqual(type(x), TestUser)
self.assertTrue(x.name in ('Test name', 'ZTest name', 'Test name2'))
self.assertTrue(x.age in (100, 53))
if x.name == 'ZTest name':
bdate = datetime(1854, 1, 6, 14, 35, 19)
self.assertEqual(x.birth_date, bdate)
self.loop.run_until_complete(_test_all())

def test_all_with_order(self):
Expand Down

0 comments on commit 4c8bb1b

Please sign in to comment.