json.py 2.5 KB

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