Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions sqlalchemy_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@
DateTimeRangeType,
EmailType,
EncryptedType,
EnrichedDateTimeType,
EnrichedDateType,
instrumented_list,
InstrumentedList,
Int8RangeType,
Expand Down
3 changes: 0 additions & 3 deletions sqlalchemy_utils/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
EncryptedType,
StringEncryptedType
)
from .enriched_datetime.enriched_date_type import EnrichedDateType # noqa
from .ip_address import IPAddressType # noqa
from .json import JSONType # noqa
from .locale import LocaleType # noqa
Expand Down Expand Up @@ -42,8 +41,6 @@
from .uuid import UUIDType # noqa
from .weekdays import WeekDaysType # noqa

from .enriched_datetime.enriched_datetime_type import EnrichedDateTimeType # noqa isort:skip


class InstrumentedList(_InstrumentedList):
"""Enhanced version of SQLAlchemy InstrumentedList. Provides some
Expand Down
63 changes: 1 addition & 62 deletions sqlalchemy_utils/types/arrow.py
Original file line number Diff line number Diff line change
@@ -1,62 +1 @@
from ..exceptions import ImproperlyConfigured
from .enriched_datetime import ArrowDateTime
from .enriched_datetime.enriched_datetime_type import EnrichedDateTimeType

arrow = None
try:
import arrow
except ImportError:
pass


class ArrowType(EnrichedDateTimeType):
"""
ArrowType provides way of saving Arrow_ objects into database. It
automatically changes Arrow_ objects to datetime objects on the way in and
datetime objects back to Arrow_ objects on the way out (when querying
database). ArrowType needs Arrow_ library installed.

.. _Arrow: https://github.com/arrow-py/arrow

::

from datetime import datetime
from sqlalchemy_utils import ArrowType
import arrow


class Article(Base):
__tablename__ = 'article'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.Unicode(255))
created_at = sa.Column(ArrowType)



article = Article(created_at=arrow.utcnow())


As you may expect all the arrow goodies come available:

::


article.created_at = article.created_at.replace(hours=-1)

article.created_at.humanize()
# 'an hour ago'

"""
cache_ok = True

def __init__(self, *args, **kwargs):
if not arrow:
raise ImproperlyConfigured(
"'arrow' package is required to use 'ArrowType'"
)

super().__init__(
datetime_processor=ArrowDateTime,
*args,
**kwargs
)
from .enriched_datetime import ArrowDateTime as ArrowType # noqa
3 changes: 1 addition & 2 deletions sqlalchemy_utils/types/enriched_datetime/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Module for enriched date, datetime type
from .arrow_datetime import ArrowDateTime # noqa
from .pendulum_date import PendulumDate # noqa
from .pendulum_datetime import PendulumDateTime # noqa
from .pendulum import PendulumDate, PendulumDateTime # noqa
42 changes: 35 additions & 7 deletions sqlalchemy_utils/types/enriched_datetime/arrow_datetime.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from collections.abc import Iterable
from datetime import datetime

from sqlalchemy import types

from ...exceptions import ImproperlyConfigured
from ..scalar_coercible import ScalarCoercible

arrow = None
try:
Expand All @@ -10,14 +13,36 @@
pass


class ArrowDateTime:
def __init__(self):
class ArrowDateTime(types.TypeDecorator, ScalarCoercible):
"""Datetime column that uses arrow dates.

Example::


from sqlalchemy_utils.enriched_datetime import ArrowDateTime
import arrow

class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
created_at = sa.Column(ArrowDateTime)

user = User()
user.created_at = arrow.now()
session.add(user)
session.commit()
"""
impl = types.DateTime
cache_ok = True

def __init__(self, *args, **kwargs):
if not arrow:
raise ImproperlyConfigured(
"'arrow' package is required to use 'ArrowDateTime'"
)
super().__init__(*args, **kwargs)

def _coerce(self, impl, value):
def _coerce(self, value):
if isinstance(value, str):
value = arrow.get(value)
elif isinstance(value, Iterable):
Expand All @@ -26,14 +51,17 @@ def _coerce(self, impl, value):
value = arrow.get(value)
return value

def process_bind_param(self, impl, value, dialect):
def process_bind_param(self, value, dialect):
if value:
utc_val = self._coerce(impl, value).to('UTC')
utc_val = self._coerce(value).to('UTC')
return utc_val.datetime\
if impl.timezone else utc_val.naive
if self.impl.timezone else utc_val.naive
return value

def process_result_value(self, impl, value, dialect):
def process_result_value(self, value, dialect):
if value:
return arrow.get(value)
return value

def process_literal_param(self, value, dialect):
return value
50 changes: 0 additions & 50 deletions sqlalchemy_utils/types/enriched_datetime/enriched_date_type.py

This file was deleted.

51 changes: 0 additions & 51 deletions sqlalchemy_utils/types/enriched_datetime/enriched_datetime_type.py

This file was deleted.

94 changes: 94 additions & 0 deletions sqlalchemy_utils/types/enriched_datetime/pendulum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import datetime

from sqlalchemy import types

from ...exceptions import ImproperlyConfigured
from ..scalar_coercible import ScalarCoercible

pendulum = None
try:
import pendulum
except ImportError:
pass


class PendulumDateTime(types.TypeDecorator, ScalarCoercible):
"""Datetime column that uses PendulumDateTime as values.

Example::


from sqlalchemy_utils.enriched_datetime import PendulumDateTime
import pendulum

class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
created_at = sa.Column(PendulumDateTime)

user = User()
user.created_at = pendulum.now()
session.add(user)
session.commit()
"""

impl = types.DateTime
cache_ok = True

def __init__(self, *args, **kwargs):
if not pendulum:
raise ImproperlyConfigured(
"'pendulum' package is required to use 'PendulumDateTime'"
)
super().__init__(*args, **kwargs)

def _coerce(self, value):
if value is not None:
if isinstance(value, pendulum.DateTime):
pass
elif isinstance(value, (int, float)):
value = pendulum.from_timestamp(value)
elif isinstance(value, str) and value.isdigit():
value = pendulum.from_timestamp(int(value))
elif isinstance(value, datetime.datetime):
value = pendulum.DateTime.instance(value)
else:
value = pendulum.parse(value)
return value

def process_bind_param(self, value, dialect):
if value:
return self._coerce(value).in_tz('UTC').naive()
return value

def process_result_value(self, value, dialect):
if value:
return pendulum.DateTime.instance(
value.replace(tzinfo=datetime.timezone.utc)
)
return value

def process_literal_param(self, value, dialect):
return value


class PendulumDate(PendulumDateTime):

cache_ok = True
impl = types.Date

def _coerce(self, value):
if value:
if not isinstance(value, pendulum.Date):
value = super()._coerce(value).date()
return value

def process_result_value(self, value, dialect):
if value:
return pendulum.parse(value.isoformat()).date()
return value

def process_bind_param(self, value, dialect):
if value:
return self._coerce(value)
return value
32 changes: 0 additions & 32 deletions sqlalchemy_utils/types/enriched_datetime/pendulum_date.py

This file was deleted.

Loading