Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy_utils/types/timezone.py: 25%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

44 statements  

1from sqlalchemy import types 

2 

3from ..exceptions import ImproperlyConfigured 

4from .scalar_coercible import ScalarCoercible 

5 

6 

7class TimezoneType(ScalarCoercible, types.TypeDecorator): 

8 """ 

9 TimezoneType provides a way for saving timezones objects into database. 

10 TimezoneType saves timezone objects as strings on the way in and converts 

11 them back to objects when querying the database. 

12 

13 :: 

14 

15 from sqlalchemy_utils import TimezoneType 

16 

17 class User(Base): 

18 __tablename__ = 'user' 

19 

20 # Pass backend='pytz' to change it to use pytz. Other values: 

21 # 'dateutil' (default), and 'zoneinfo'. 

22 timezone = sa.Column(TimezoneType(backend='pytz')) 

23 

24 :param backend: 

25 Whether to use 'dateutil', 'pytz' or 'zoneinfo' for timezones. 

26 'zoneinfo' uses the standard library module. 

27 

28 """ 

29 

30 impl = types.Unicode(50) 

31 python_type = None 

32 cache_ok = True 

33 

34 def __init__(self, backend='dateutil'): 

35 self.backend = backend 

36 if backend == 'dateutil': 

37 try: 

38 from dateutil.tz import tzfile 

39 from dateutil.zoneinfo import get_zonefile_instance 

40 

41 self.python_type = tzfile 

42 self._to = get_zonefile_instance().zones.get 

43 self._from = lambda x: str(x._filename) 

44 

45 except ImportError: 

46 raise ImproperlyConfigured( 

47 "'python-dateutil' is required to use the " 

48 "'dateutil' backend for 'TimezoneType'" 

49 ) 

50 

51 elif backend == 'pytz': 

52 try: 

53 from pytz import timezone 

54 from pytz.tzinfo import BaseTzInfo 

55 

56 self.python_type = BaseTzInfo 

57 self._to = timezone 

58 self._from = str 

59 

60 except ImportError: 

61 raise ImproperlyConfigured( 

62 "'pytz' is required to use the 'pytz' backend for 'TimezoneType'" 

63 ) 

64 

65 elif backend == 'zoneinfo': 

66 import zoneinfo 

67 

68 self.python_type = zoneinfo.ZoneInfo 

69 self._to = zoneinfo.ZoneInfo 

70 self._from = str 

71 

72 else: 

73 raise ImproperlyConfigured( 

74 "'pytz', 'dateutil' or 'zoneinfo' are the backends " 

75 "supported for 'TimezoneType'" 

76 ) 

77 

78 def _coerce(self, value): 

79 if value is not None and not isinstance(value, self.python_type): 

80 obj = self._to(value) 

81 if obj is None: 

82 raise ValueError("unknown time zone '%s'" % value) 

83 return obj 

84 return value 

85 

86 def process_bind_param(self, value, dialect): 

87 return self._from(self._coerce(value)) if value else None 

88 

89 def process_result_value(self, value, dialect): 

90 return self._to(value) if value else None