1from sqlalchemy import types
2
3from .. import i18n, ImproperlyConfigured
4from ..primitives import Currency
5from .scalar_coercible import ScalarCoercible
6
7
8class CurrencyType(ScalarCoercible, types.TypeDecorator):
9 """
10 Changes :class:`.Currency` objects to a string representation on the way in
11 and changes them back to :class:`.Currency` objects on the way out.
12
13 In order to use CurrencyType you need to install Babel_ first.
14
15 .. _Babel: https://babel.pocoo.org/
16
17 ::
18
19
20 from sqlalchemy_utils import CurrencyType, Currency
21
22
23 class User(Base):
24 __tablename__ = 'user'
25 id = sa.Column(sa.Integer, autoincrement=True)
26 name = sa.Column(sa.Unicode(255))
27 currency = sa.Column(CurrencyType)
28
29
30 user = User()
31 user.currency = Currency('USD')
32 session.add(user)
33 session.commit()
34
35 user.currency # Currency('USD')
36 user.currency.name # US Dollar
37
38 str(user.currency) # US Dollar
39 user.currency.symbol # $
40
41
42
43 CurrencyType is scalar coercible::
44
45
46 user.currency = 'US'
47 user.currency # Currency('US')
48 """
49
50 impl = types.String(3)
51 python_type = Currency
52 cache_ok = True
53
54 def __init__(self, *args, **kwargs):
55 if i18n.babel is None:
56 raise ImproperlyConfigured(
57 "'babel' package is required in order to use CurrencyType."
58 )
59
60 super().__init__(*args, **kwargs)
61
62 def process_bind_param(self, value, dialect):
63 if isinstance(value, Currency):
64 return value.code
65 elif isinstance(value, str):
66 return value
67
68 def process_result_value(self, value, dialect):
69 if value is not None:
70 return Currency(value)
71
72 def _coerce(self, value):
73 if value is not None and not isinstance(value, Currency):
74 return Currency(value)
75 return value