Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy/dialects/sqlite/json.py: 43%

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

47 statements  

1# dialects/sqlite/json.py 

2# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of SQLAlchemy and is released under 

6# the MIT License: https://www.opensource.org/licenses/mit-license.php 

7from __future__ import annotations 

8 

9from typing import Any 

10from typing import TYPE_CHECKING 

11 

12from ... import types as sqltypes 

13from ...sql import func 

14from ...sql.sqltypes import _T_JSON 

15 

16if TYPE_CHECKING: 

17 from ...engine.interfaces import Dialect 

18 from ...sql.elements import ColumnElement 

19 from ...sql.type_api import _BindProcessorType 

20 from ...sql.type_api import _LiteralProcessorType 

21 

22 

23class JSON(sqltypes.JSON[_T_JSON]): 

24 """SQLite JSON type. 

25 

26 SQLite supports JSON as of version 3.9 through its JSON1_ extension. Note 

27 that JSON1_ is a 

28 `loadable extension <https://www.sqlite.org/loadext.html>`_ and as such 

29 may not be available, or may require run-time loading. 

30 

31 :class:`_sqlite.JSON` is used automatically whenever the base 

32 :class:`_types.JSON` datatype is used against a SQLite backend. 

33 

34 .. seealso:: 

35 

36 :class:`_types.JSON` - main documentation for the generic 

37 cross-platform JSON datatype. 

38 

39 The :class:`_sqlite.JSON` type supports persistence of JSON values 

40 as well as the core index operations provided by :class:`_types.JSON` 

41 datatype, by adapting the operations to render the ``JSON_EXTRACT`` 

42 function wrapped in the ``JSON_QUOTE`` function at the database level. 

43 Extracted values are quoted in order to ensure that the results are 

44 always JSON string values. 

45 

46 

47 .. _JSON1: https://www.sqlite.org/json1.html 

48 

49 """ 

50 

51 

52class JSONB(JSON[_T_JSON]): 

53 """SQLite JSONB type. 

54 

55 Stores JSON data in SQLite's binary JSONB format, available as of 

56 SQLite version 3.45.0. The binary format is more compact and faster 

57 to parse than the text-based :class:`_sqlite.JSON` type. 

58 

59 Values are transparently stored using the ``jsonb()`` SQL function and 

60 retrieved as text JSON via the ``json()`` SQL function, so the Python 

61 side behaves identically to :class:`_sqlite.JSON`. 

62 

63 .. versionadded:: 2.1b3 

64 

65 .. seealso:: 

66 

67 :class:`_sqlite.JSON` 

68 

69 https://sqlite.org/jsonb.html 

70 

71 """ 

72 

73 __visit_name__ = "JSONB" 

74 

75 def bind_expression( 

76 self, bindvalue: ColumnElement[Any] 

77 ) -> ColumnElement[Any]: 

78 return func.jsonb(bindvalue, type_=self) 

79 

80 def column_expression(self, col: ColumnElement[Any]) -> ColumnElement[Any]: 

81 return func.json(col, type_=self) 

82 

83 

84# Note: these objects currently match exactly those of MySQL, however since 

85# these are not generalizable to all JSON implementations, remain separately 

86# implemented for each dialect. 

87class _FormatTypeMixin: 

88 def _format_value(self, value: Any) -> str: 

89 raise NotImplementedError() 

90 

91 def bind_processor(self, dialect: Dialect) -> _BindProcessorType[Any]: 

92 super_proc = self.string_bind_processor(dialect) # type: ignore[attr-defined] # noqa: E501 

93 

94 def process(value: Any) -> Any: 

95 value = self._format_value(value) 

96 if super_proc: 

97 value = super_proc(value) 

98 return value 

99 

100 return process 

101 

102 def literal_processor( 

103 self, dialect: Dialect 

104 ) -> _LiteralProcessorType[Any]: 

105 super_proc = self.string_literal_processor(dialect) # type: ignore[attr-defined] # noqa: E501 

106 

107 def process(value: Any) -> str: 

108 value = self._format_value(value) 

109 if super_proc: 

110 value = super_proc(value) 

111 return value # type: ignore[no-any-return] 

112 

113 return process 

114 

115 

116class JSONIndexType(_FormatTypeMixin, sqltypes.JSON.JSONIndexType): 

117 def _format_value(self, value: Any) -> str: 

118 if isinstance(value, int): 

119 formatted_value = "$[%s]" % value 

120 else: 

121 formatted_value = '$."%s"' % value 

122 return formatted_value 

123 

124 

125class JSONPathType(_FormatTypeMixin, sqltypes.JSON.JSONPathType): 

126 def _format_value(self, value: Any) -> str: 

127 return "$%s" % ( 

128 "".join( 

129 [ 

130 "[%s]" % elem if isinstance(elem, int) else '."%s"' % elem 

131 for elem in value 

132 ] 

133 ) 

134 )