json.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. # dialects/sqlite/json.py
  2. # Copyright (C) 2005-2025 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
  7. # mypy: ignore-errors
  8. from ... import types as sqltypes
  9. class JSON(sqltypes.JSON):
  10. """SQLite JSON type.
  11. SQLite supports JSON as of version 3.9 through its JSON1_ extension. Note
  12. that JSON1_ is a
  13. `loadable extension <https://www.sqlite.org/loadext.html>`_ and as such
  14. may not be available, or may require run-time loading.
  15. :class:`_sqlite.JSON` is used automatically whenever the base
  16. :class:`_types.JSON` datatype is used against a SQLite backend.
  17. .. seealso::
  18. :class:`_types.JSON` - main documentation for the generic
  19. cross-platform JSON datatype.
  20. The :class:`_sqlite.JSON` type supports persistence of JSON values
  21. as well as the core index operations provided by :class:`_types.JSON`
  22. datatype, by adapting the operations to render the ``JSON_EXTRACT``
  23. function wrapped in the ``JSON_QUOTE`` function at the database level.
  24. Extracted values are quoted in order to ensure that the results are
  25. always JSON string values.
  26. .. versionadded:: 1.3
  27. .. _JSON1: https://www.sqlite.org/json1.html
  28. """
  29. # Note: these objects currently match exactly those of MySQL, however since
  30. # these are not generalizable to all JSON implementations, remain separately
  31. # implemented for each dialect.
  32. class _FormatTypeMixin:
  33. def _format_value(self, value):
  34. raise NotImplementedError()
  35. def bind_processor(self, dialect):
  36. super_proc = self.string_bind_processor(dialect)
  37. def process(value):
  38. value = self._format_value(value)
  39. if super_proc:
  40. value = super_proc(value)
  41. return value
  42. return process
  43. def literal_processor(self, dialect):
  44. super_proc = self.string_literal_processor(dialect)
  45. def process(value):
  46. value = self._format_value(value)
  47. if super_proc:
  48. value = super_proc(value)
  49. return value
  50. return process
  51. class JSONIndexType(_FormatTypeMixin, sqltypes.JSON.JSONIndexType):
  52. def _format_value(self, value):
  53. if isinstance(value, int):
  54. value = "$[%s]" % value
  55. else:
  56. value = '$."%s"' % value
  57. return value
  58. class JSONPathType(_FormatTypeMixin, sqltypes.JSON.JSONPathType):
  59. def _format_value(self, value):
  60. return "$%s" % (
  61. "".join(
  62. [
  63. "[%s]" % elem if isinstance(elem, int) else '."%s"' % elem
  64. for elem in value
  65. ]
  66. )
  67. )