compat.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import re
  2. import sys
  3. if sys.version_info >= (3, 8):
  4. from importlib.metadata import metadata
  5. else:
  6. from importlib_metadata import metadata
  7. def get_sqlalchemy_version(version=metadata("sqlalchemy")["Version"]):
  8. """Extract the sqlalchemy version as a tuple of integers."""
  9. match = re.search(r"^(\d+)(?:\.(\d+)(?:\.(\d+))?)?", version)
  10. try:
  11. return tuple(int(v) for v in match.groups() if v is not None)
  12. except AttributeError:
  13. return ()
  14. _sqlalchemy_version = get_sqlalchemy_version()
  15. # In sqlalchemy 2.0, some functions moved to sqlalchemy.orm.
  16. # In sqlalchemy 1.3, they are only available in .ext.declarative.
  17. # In sqlalchemy 1.4, they are available in both places.
  18. #
  19. # WARNING
  20. # -------
  21. #
  22. # These imports are for internal, private compatibility.
  23. # They are not supported and may change or move at any time.
  24. # Do not import these in your own code.
  25. #
  26. if _sqlalchemy_version >= (1, 4):
  27. from sqlalchemy.orm import declarative_base as _declarative_base
  28. from sqlalchemy.orm import synonym_for as _synonym_for
  29. else:
  30. from sqlalchemy.ext.declarative import \
  31. declarative_base as _declarative_base
  32. from sqlalchemy.ext.declarative import synonym_for as _synonym_for
  33. # scalar subqueries
  34. if _sqlalchemy_version >= (1, 4):
  35. def get_scalar_subquery(query):
  36. return query.scalar_subquery()
  37. else:
  38. def get_scalar_subquery(query):
  39. return query.as_scalar()
  40. # In sqlalchemy 2.0, select() columns are positional.
  41. # In sqlalchemy 1.3, select() columns must be wrapped in a list.
  42. #
  43. # _select_args() is designed so its return value can be unpacked:
  44. #
  45. # select(*_select_args(1, 2))
  46. #
  47. # When sqlalchemy 1.3 support is dropped, remove the call to _select_args()
  48. # and keep the arguments the same:
  49. #
  50. # select(1, 2)
  51. #
  52. # WARNING
  53. # -------
  54. #
  55. # _select_args() is a private, internal function.
  56. # It is not supported and may change or move at any time.
  57. # Do not import this in your own code.
  58. #
  59. if _sqlalchemy_version >= (1, 4):
  60. def _select_args(*args):
  61. return args
  62. else:
  63. def _select_args(*args):
  64. return [args]
  65. __all__ = (
  66. "_declarative_base",
  67. "get_scalar_subquery",
  68. "get_sqlalchemy_version",
  69. "_select_args",
  70. "_synonym_for",
  71. )