meerschaum 2.9.0rc2__tar.gz → 2.9.0rc3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. {meerschaum-2.9.0rc2/meerschaum.egg-info → meerschaum-2.9.0rc3}/PKG-INFO +14 -7
  2. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_pipes.py +27 -2
  3. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_version.py +1 -1
  4. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/valkey/_ValkeyConnector.py +2 -0
  5. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/valkey/_pipes.py +50 -39
  6. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/__init__.py +1 -0
  7. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_sync.py +64 -4
  8. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/dataframe.py +51 -3
  9. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/dtypes/__init__.py +35 -6
  10. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/dtypes/sql.py +182 -3
  11. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/packages/_packages.py +6 -2
  12. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/sql.py +88 -6
  13. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/venv/__init__.py +4 -1
  14. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3/meerschaum.egg-info}/PKG-INFO +14 -7
  15. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum.egg-info/requires.txt +14 -6
  16. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_pipes_dtypes.py +8 -4
  17. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/LICENSE +0 -0
  18. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/NOTICE +0 -0
  19. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/README.md +0 -0
  20. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/__init__.py +0 -0
  21. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/__main__.py +0 -0
  22. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/__init__.py +0 -0
  23. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/arguments/__init__.py +0 -0
  24. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/arguments/_parse_arguments.py +0 -0
  25. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/arguments/_parser.py +0 -0
  26. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/docs/__init__.py +0 -0
  27. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/docs/index.py +0 -0
  28. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/entry.py +0 -0
  29. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/gui/__init__.py +0 -0
  30. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/gui/app/__init__.py +0 -0
  31. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/gui/app/_windows.py +0 -0
  32. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/gui/app/actions.py +0 -0
  33. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/gui/app/pipes.py +0 -0
  34. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/shell/Shell.py +0 -0
  35. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/shell/ShellCompleter.py +0 -0
  36. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/shell/ValidAutoSuggest.py +0 -0
  37. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/shell/__init__.py +0 -0
  38. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/shell/resources/__init__.py +0 -0
  39. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/shell/updates.py +0 -0
  40. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/term/TermPageHandler.py +0 -0
  41. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/term/__init__.py +0 -0
  42. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/_internal/term/tools.py +0 -0
  43. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/__init__.py +0 -0
  44. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/api.py +0 -0
  45. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/attach.py +0 -0
  46. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/bootstrap.py +0 -0
  47. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/clear.py +0 -0
  48. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/copy.py +0 -0
  49. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/deduplicate.py +0 -0
  50. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/delete.py +0 -0
  51. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/drop.py +0 -0
  52. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/edit.py +0 -0
  53. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/index.py +0 -0
  54. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/install.py +0 -0
  55. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/login.py +0 -0
  56. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/os.py +0 -0
  57. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/pause.py +0 -0
  58. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/python.py +0 -0
  59. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/register.py +0 -0
  60. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/reload.py +0 -0
  61. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/restart.py +0 -0
  62. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/setup.py +0 -0
  63. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/sh.py +0 -0
  64. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/show.py +0 -0
  65. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/sql.py +0 -0
  66. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/stack.py +0 -0
  67. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/start.py +0 -0
  68. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/stop.py +0 -0
  69. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/sync.py +0 -0
  70. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/tag.py +0 -0
  71. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/uninstall.py +0 -0
  72. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/upgrade.py +0 -0
  73. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/actions/verify.py +0 -0
  74. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/__init__.py +0 -0
  75. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/_chain.py +0 -0
  76. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/_chunks.py +0 -0
  77. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/_events.py +0 -0
  78. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/_exceptions.py +0 -0
  79. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/_oauth2.py +0 -0
  80. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/_websockets.py +0 -0
  81. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/__init__.py +0 -0
  82. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/assets/__init__.py +0 -0
  83. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/assets/ansi_up.js +0 -0
  84. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/assets/banner_1920x320.png +0 -0
  85. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/assets/favicon.ico +0 -0
  86. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/assets/logo_48x48.png +0 -0
  87. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/assets/logo_500x500.png +0 -0
  88. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/__init__.py +0 -0
  89. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/custom.py +0 -0
  90. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/dashboard.py +0 -0
  91. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/jobs.py +0 -0
  92. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/login.py +0 -0
  93. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/pipes.py +0 -0
  94. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/plugins.py +0 -0
  95. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/callbacks/register.py +0 -0
  96. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/components.py +0 -0
  97. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/connectors.py +0 -0
  98. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/graphs.py +0 -0
  99. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/jobs.py +0 -0
  100. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/keys.py +0 -0
  101. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/__init__.py +0 -0
  102. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/dashboard.py +0 -0
  103. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/error.py +0 -0
  104. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/job.py +0 -0
  105. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/login.py +0 -0
  106. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/pipes.py +0 -0
  107. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/plugins.py +0 -0
  108. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pages/register.py +0 -0
  109. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/pipes.py +0 -0
  110. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/plugins.py +0 -0
  111. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/sessions.py +0 -0
  112. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/sync.py +0 -0
  113. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/users.py +0 -0
  114. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/websockets.py +0 -0
  115. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/dash/webterm.py +0 -0
  116. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/models/__init__.py +0 -0
  117. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/models/_interfaces.py +0 -0
  118. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/models/_locations.py +0 -0
  119. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/models/_metrics.py +0 -0
  120. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/models/_pipes.py +0 -0
  121. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/__init__.py +0 -0
  122. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/__init__.py +0 -0
  123. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/css/__init__.py +0 -0
  124. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/css/bootstrap.min.css +0 -0
  125. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/css/dash.css +0 -0
  126. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/css/dbc_dark.css +0 -0
  127. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/css/styles.css +0 -0
  128. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/css/xterm.css +0 -0
  129. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/ico/__init__.py +0 -0
  130. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/ico/logo.ico +0 -0
  131. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/js/__init__.py +0 -0
  132. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/js/action_button.js +0 -0
  133. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/js/main.js +0 -0
  134. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/js/terminado.js +0 -0
  135. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/js/xterm.js +0 -0
  136. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/static/png/__init__.py +0 -0
  137. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/templates/__init__.py +0 -0
  138. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/templates/index.html +0 -0
  139. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/templates/old_index.html +0 -0
  140. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/templates/secret.html +0 -0
  141. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/resources/templates/termpage.html +0 -0
  142. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/__init__.py +0 -0
  143. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_actions.py +0 -0
  144. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_connectors.py +0 -0
  145. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_index.py +0 -0
  146. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_jobs.py +0 -0
  147. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_login.py +0 -0
  148. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_misc.py +0 -0
  149. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_plugins.py +0 -0
  150. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_users.py +0 -0
  151. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_version.py +0 -0
  152. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/routes/_webterm.py +0 -0
  153. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/api/tables/__init__.py +0 -0
  154. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/__init__.py +0 -0
  155. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_dash.py +0 -0
  156. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_default.py +0 -0
  157. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_edit.py +0 -0
  158. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_environment.py +0 -0
  159. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_formatting.py +0 -0
  160. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_jobs.py +0 -0
  161. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_patch.py +0 -0
  162. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_paths.py +0 -0
  163. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_preprocess.py +0 -0
  164. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_read_config.py +0 -0
  165. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_shell.py +0 -0
  166. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/_sync.py +0 -0
  167. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/paths.py +0 -0
  168. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/resources/__init__.py +0 -0
  169. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/stack/__init__.py +0 -0
  170. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/stack/grafana/__init__.py +0 -0
  171. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/stack/mosquitto/__init__.py +0 -0
  172. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/stack/mosquitto/resources/__init__.py +0 -0
  173. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/stack/resources/__init__.py +0 -0
  174. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/config/static/__init__.py +0 -0
  175. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/_Connector.py +0 -0
  176. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/__init__.py +0 -0
  177. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_APIConnector.py +0 -0
  178. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/__init__.py +0 -0
  179. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_actions.py +0 -0
  180. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_fetch.py +0 -0
  181. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_jobs.py +0 -0
  182. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_login.py +0 -0
  183. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_misc.py +0 -0
  184. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_pipes.py +0 -0
  185. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_plugins.py +0 -0
  186. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_request.py +0 -0
  187. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_uri.py +0 -0
  188. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/api/_users.py +0 -0
  189. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/parse.py +0 -0
  190. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/plugin/PluginConnector.py +0 -0
  191. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/plugin/__init__.py +0 -0
  192. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/poll.py +0 -0
  193. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_SQLConnector.py +0 -0
  194. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/__init__.py +0 -0
  195. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_cli.py +0 -0
  196. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_create_engine.py +0 -0
  197. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_fetch.py +0 -0
  198. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_instance.py +0 -0
  199. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_pipes.py +0 -0
  200. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_plugins.py +0 -0
  201. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_sql.py +0 -0
  202. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_uri.py +0 -0
  203. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/_users.py +0 -0
  204. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/tables/__init__.py +0 -0
  205. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/tables/types.py +0 -0
  206. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/sql/tools.py +0 -0
  207. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/valkey/__init__.py +0 -0
  208. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/valkey/_fetch.py +0 -0
  209. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/valkey/_plugins.py +0 -0
  210. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/connectors/valkey/_users.py +0 -0
  211. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_attributes.py +0 -0
  212. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_bootstrap.py +0 -0
  213. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_clear.py +0 -0
  214. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_copy.py +0 -0
  215. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_data.py +0 -0
  216. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_deduplicate.py +0 -0
  217. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_delete.py +0 -0
  218. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_drop.py +0 -0
  219. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_dtypes.py +0 -0
  220. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_edit.py +0 -0
  221. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_fetch.py +0 -0
  222. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_index.py +0 -0
  223. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_register.py +0 -0
  224. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_show.py +0 -0
  225. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Pipe/_verify.py +0 -0
  226. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/Plugin/__init__.py +0 -0
  227. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/User/_User.py +0 -0
  228. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/User/__init__.py +0 -0
  229. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/core/__init__.py +0 -0
  230. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/jobs/_Executor.py +0 -0
  231. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/jobs/_Job.py +0 -0
  232. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/jobs/__init__.py +0 -0
  233. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/jobs/systemd.py +0 -0
  234. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/plugins/_Plugin.py +0 -0
  235. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/plugins/__init__.py +0 -0
  236. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/plugins/bootstrap.py +0 -0
  237. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/__init__.py +0 -0
  238. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/_get_pipes.py +0 -0
  239. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/daemon/Daemon.py +0 -0
  240. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -0
  241. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/daemon/RotatingFile.py +0 -0
  242. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/daemon/StdinFile.py +0 -0
  243. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/daemon/__init__.py +0 -0
  244. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/daemon/_names.py +0 -0
  245. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/debug.py +0 -0
  246. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/formatting/__init__.py +0 -0
  247. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/formatting/_jobs.py +0 -0
  248. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/formatting/_pipes.py +0 -0
  249. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/formatting/_pprint.py +0 -0
  250. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/formatting/_shell.py +0 -0
  251. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/interactive.py +0 -0
  252. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/misc.py +0 -0
  253. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/networking.py +0 -0
  254. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/packages/__init__.py +0 -0
  255. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/packages/lazy_loader.py +0 -0
  256. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/pool.py +0 -0
  257. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/process.py +0 -0
  258. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/prompt.py +0 -0
  259. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/schedule.py +0 -0
  260. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/threading.py +0 -0
  261. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/typing.py +0 -0
  262. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/venv/_Venv.py +0 -0
  263. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/warnings.py +0 -0
  264. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum/utils/yaml.py +0 -0
  265. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum.egg-info/SOURCES.txt +0 -0
  266. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum.egg-info/dependency_links.txt +0 -0
  267. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum.egg-info/entry_points.txt +0 -0
  268. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum.egg-info/top_level.txt +0 -0
  269. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/meerschaum.egg-info/zip-safe +0 -0
  270. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/setup.cfg +0 -0
  271. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/setup.py +0 -0
  272. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_actions.py +0 -0
  273. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_arguments.py +0 -0
  274. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_deduplicate.py +0 -0
  275. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_jobs.py +0 -0
  276. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_pipe_data.py +0 -0
  277. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_sql.py +0 -0
  278. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_sync.py +0 -0
  279. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_users.py +0 -0
  280. {meerschaum-2.9.0rc2 → meerschaum-2.9.0rc3}/tests/test_verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: meerschaum
3
- Version: 2.9.0rc2
3
+ Version: 2.9.0rc3
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Home-page: https://meerschaum.io
6
6
  Author: Bennett Meares
@@ -87,6 +87,10 @@ Requires-Dist: mycli>=1.23.2; extra == "cli"
87
87
  Requires-Dist: litecli>=1.5.0; extra == "cli"
88
88
  Requires-Dist: mssql-cli>=1.0.0; extra == "cli"
89
89
  Requires-Dist: gadwall>=0.2.0; extra == "cli"
90
+ Provides-Extra: gis
91
+ Requires-Dist: pyproj>=3.7.1; extra == "gis"
92
+ Requires-Dist: geopandas>=1.0.1; extra == "gis"
93
+ Requires-Dist: shapely>=2.0.7; extra == "gis"
90
94
  Provides-Extra: stack
91
95
  Requires-Dist: docker-compose>=1.29.2; extra == "stack"
92
96
  Provides-Extra: build
@@ -126,8 +130,6 @@ Requires-Dist: importlib-metadata>=4.12.0; extra == "extras"
126
130
  Provides-Extra: sql
127
131
  Requires-Dist: numpy>=1.18.5; extra == "sql"
128
132
  Requires-Dist: pandas[parquet]>=2.0.1; extra == "sql"
129
- Requires-Dist: geopandas>=1.0.1; extra == "sql"
130
- Requires-Dist: shapely>=2.0.7; extra == "sql"
131
133
  Requires-Dist: pyarrow>=16.1.0; extra == "sql"
132
134
  Requires-Dist: dask[complete]>=2024.12.1; extra == "sql"
133
135
  Requires-Dist: partd>=1.4.2; extra == "sql"
@@ -167,6 +169,9 @@ Requires-Dist: fasteners>=0.19.0; extra == "sql"
167
169
  Requires-Dist: virtualenv>=20.1.0; extra == "sql"
168
170
  Requires-Dist: attrs>=24.2.0; extra == "sql"
169
171
  Requires-Dist: uv>=0.2.11; extra == "sql"
172
+ Requires-Dist: pyproj>=3.7.1; extra == "sql"
173
+ Requires-Dist: geopandas>=1.0.1; extra == "sql"
174
+ Requires-Dist: shapely>=2.0.7; extra == "sql"
170
175
  Provides-Extra: dash
171
176
  Requires-Dist: Flask-Compress>=1.10.1; extra == "dash"
172
177
  Requires-Dist: dash>=2.6.2; extra == "dash"
@@ -189,8 +194,6 @@ Requires-Dist: httpcore>=1.0.6; extra == "api"
189
194
  Requires-Dist: valkey>=6.0.0; extra == "api"
190
195
  Requires-Dist: numpy>=1.18.5; extra == "api"
191
196
  Requires-Dist: pandas[parquet]>=2.0.1; extra == "api"
192
- Requires-Dist: geopandas>=1.0.1; extra == "api"
193
- Requires-Dist: shapely>=2.0.7; extra == "api"
194
197
  Requires-Dist: pyarrow>=16.1.0; extra == "api"
195
198
  Requires-Dist: dask[complete]>=2024.12.1; extra == "api"
196
199
  Requires-Dist: partd>=1.4.2; extra == "api"
@@ -230,6 +233,9 @@ Requires-Dist: fasteners>=0.19.0; extra == "api"
230
233
  Requires-Dist: virtualenv>=20.1.0; extra == "api"
231
234
  Requires-Dist: attrs>=24.2.0; extra == "api"
232
235
  Requires-Dist: uv>=0.2.11; extra == "api"
236
+ Requires-Dist: pyproj>=3.7.1; extra == "api"
237
+ Requires-Dist: geopandas>=1.0.1; extra == "api"
238
+ Requires-Dist: shapely>=2.0.7; extra == "api"
233
239
  Requires-Dist: pprintpp>=0.4.0; extra == "api"
234
240
  Requires-Dist: asciitree>=0.3.3; extra == "api"
235
241
  Requires-Dist: typing-extensions>=4.7.1; extra == "api"
@@ -292,13 +298,14 @@ Requires-Dist: aiomysql>=0.0.21; extra == "full"
292
298
  Requires-Dist: sqlalchemy-cockroachdb>=2.0.0; extra == "full"
293
299
  Requires-Dist: duckdb>=1.0.0; extra == "full"
294
300
  Requires-Dist: duckdb-engine>=0.13.0; extra == "full"
301
+ Requires-Dist: pyproj>=3.7.1; extra == "full"
302
+ Requires-Dist: geopandas>=1.0.1; extra == "full"
303
+ Requires-Dist: shapely>=2.0.7; extra == "full"
295
304
  Requires-Dist: toga>=0.3.0-dev29; extra == "full"
296
305
  Requires-Dist: pywebview>=3.6.3; extra == "full"
297
306
  Requires-Dist: pycparser>=2.21.0; extra == "full"
298
307
  Requires-Dist: numpy>=1.18.5; extra == "full"
299
308
  Requires-Dist: pandas[parquet]>=2.0.1; extra == "full"
300
- Requires-Dist: geopandas>=1.0.1; extra == "full"
301
- Requires-Dist: shapely>=2.0.7; extra == "full"
302
309
  Requires-Dist: pyarrow>=16.1.0; extra == "full"
303
310
  Requires-Dist: dask[complete]>=2024.12.1; extra == "full"
304
311
  Requires-Dist: partd>=1.4.2; extra == "full"
@@ -383,6 +383,10 @@ def get_pipe_data(
383
383
  params: Optional[str] = None,
384
384
  limit: int = MAX_RESPONSE_ROW_LIMIT,
385
385
  order: str = 'asc',
386
+ date_format: str = 'iso',
387
+ date_unit: str = 'us',
388
+ double_precision: int = 15,
389
+ geometry_format: str = 'wkb_hex',
386
390
  as_chunks: bool = False,
387
391
  chunk_interval: Optional[int] = None,
388
392
  curr_user = (
@@ -401,6 +405,21 @@ def get_pipe_data(
401
405
  The connector key to the instance on which the pipe is registered.
402
406
  Defaults to the configured value for `meerschaum:api_instance`.
403
407
 
408
+ date_format: str, default 'iso'
409
+ Serialzation format for datetime values.
410
+ Accepted values are `'iso`' (ISO8601) and `'epoch'` (epoch milliseconds).
411
+
412
+ date_unit: str, default 'us'
413
+ Timestamp precision for serialization. Accepted values are `'s'` (seconds),
414
+ `'ms'` (milliseconds), `'us'` (microseconds), and `'ns'`.
415
+
416
+ double_precision: int, default 15
417
+ The number of decimal places to use when encoding floating point values (maximum 15).
418
+
419
+ geometry_format: str, default 'wkb_hex'
420
+ The serialization format for geometry data.
421
+ Accepted values are `geojson`, `wkb_hex`, and `wkt`.
422
+
404
423
  as_chunks: bool, default False
405
424
  If `True`, return a chunk token to be consumed by the `/chunks` endpoint.
406
425
  """
@@ -483,7 +502,7 @@ def get_pipe_data(
483
502
  )
484
503
  return fastapi.Response(
485
504
  json.dumps({
486
- 'chunks_cursor': chunks_cursor,
505
+ 'chunks_cursor': chunks_cursor_token,
487
506
  }),
488
507
  media_type='application/json',
489
508
  )
@@ -504,7 +523,13 @@ def get_pipe_data(
504
523
  detail="Could not fetch data with the given parameters.",
505
524
  )
506
525
 
507
- json_content = to_json(df)
526
+ json_content = to_json(
527
+ df,
528
+ date_format=date_format,
529
+ date_unit=date_unit,
530
+ geometry_format=geometry_format,
531
+ double_precision=double_precision,
532
+ )
508
533
  return fastapi.Response(
509
534
  json_content,
510
535
  media_type='application/json',
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.9.0rc2"
5
+ __version__ = "2.9.0rc3"
@@ -50,6 +50,8 @@ class ValkeyConnector(Connector):
50
50
  get_sync_time,
51
51
  get_pipe_rowcount,
52
52
  fetch_pipes_keys,
53
+ get_document_key,
54
+ get_table_quoted_doc_key,
53
55
  )
54
56
  from ._fetch import (
55
57
  fetch,
@@ -10,8 +10,9 @@ from datetime import datetime, timezone
10
10
 
11
11
  import meerschaum as mrsm
12
12
  from meerschaum.utils.typing import SuccessTuple, Any, Union, Optional, Dict, List, Tuple
13
- from meerschaum.utils.misc import json_serialize_datetime, string_to_dict
14
- from meerschaum.utils.warnings import warn
13
+ from meerschaum.utils.misc import string_to_dict
14
+ from meerschaum.utils.dtypes import json_serialize_value
15
+ from meerschaum.utils.warnings import warn, dprint
15
16
  from meerschaum.config.static import STATIC_CONFIG
16
17
 
17
18
  PIPES_TABLE: str = 'mrsm_pipes'
@@ -46,25 +47,15 @@ def serialize_document(doc: Dict[str, Any]) -> str:
46
47
  -------
47
48
  A serialized string for the document.
48
49
  """
49
- from meerschaum.utils.dtypes import serialize_bytes
50
50
  return json.dumps(
51
51
  doc,
52
- default=(
53
- lambda x: (
54
- json_serialize_datetime(x)
55
- if hasattr(x, 'tzinfo')
56
- else (
57
- serialize_bytes(x)
58
- if isinstance(x, bytes)
59
- else str(x)
60
- )
61
- )
62
- ),
52
+ default=json_serialize_value,
63
53
  separators=(',', ':'),
64
54
  sort_keys=True,
65
55
  )
66
56
 
67
57
 
58
+ @staticmethod
68
59
  def get_document_key(
69
60
  doc: Dict[str, Any],
70
61
  indices: List[str],
@@ -91,25 +82,39 @@ def get_document_key(
91
82
  from meerschaum.utils.dtypes import coerce_timezone
92
83
  index_vals = {
93
84
  key: (
94
- str(val)
85
+ str(val).replace(':', COLON)
95
86
  if not isinstance(val, datetime)
96
87
  else str(int(coerce_timezone(val).replace(tzinfo=timezone.utc).timestamp()))
97
88
  )
98
89
  for key, val in doc.items()
99
- if key in indices
100
- } if indices else {}
101
- indices_str = ((table_name + ':indices:') if table_name else '') + ','.join(
102
- sorted(
103
- [
104
- f'{key}{COLON}{val}'
105
- for key, val in index_vals.items()
106
- ]
90
+ if ((key in indices) if indices else True)
91
+ }
92
+ indices_str = (
93
+ (
94
+ (
95
+ (
96
+ table_name
97
+ + ':'
98
+ + ('indices:' if True else '')
99
+ )
100
+ )
101
+ if table_name
102
+ else ''
103
+ ) + ','.join(
104
+ sorted(
105
+ [
106
+ f'{key}{COLON}{val}'
107
+ for key, val in index_vals.items()
108
+ ]
109
+ )
107
110
  )
108
- ) if indices else serialize_document(doc)
111
+ )
109
112
  return indices_str
110
113
 
111
114
 
115
+ @classmethod
112
116
  def get_table_quoted_doc_key(
117
+ cls,
113
118
  table_name: str,
114
119
  doc: Dict[str, Any],
115
120
  indices: List[str],
@@ -120,7 +125,7 @@ def get_table_quoted_doc_key(
120
125
  """
121
126
  return json.dumps(
122
127
  {
123
- get_document_key(doc, indices, table_name): serialize_document(doc),
128
+ cls.get_document_key(doc, indices, table_name): serialize_document(doc),
124
129
  **(
125
130
  {datetime_column: doc.get(datetime_column, 0)}
126
131
  if datetime_column
@@ -129,7 +134,7 @@ def get_table_quoted_doc_key(
129
134
  },
130
135
  sort_keys=True,
131
136
  separators=(',', ':'),
132
- default=(lambda x: json_serialize_datetime(x) if hasattr(x, 'tzinfo') else str(x)),
137
+ default=json_serialize_value,
133
138
  )
134
139
 
135
140
 
@@ -377,7 +382,7 @@ def delete_pipe(
377
382
  doc = docs[0]
378
383
  doc_str = json.dumps(
379
384
  doc,
380
- default=(lambda x: json_serialize_datetime(x) if hasattr(x, 'tzinfo') else str(x)),
385
+ default=json_serialize_value,
381
386
  separators=(',', ':'),
382
387
  sort_keys=True,
383
388
  )
@@ -445,9 +450,13 @@ def get_pipe_data(
445
450
  ]
446
451
  try:
447
452
  docs_strings = [
448
- self.get(get_document_key(
449
- doc, indices, table_name
450
- ))
453
+ self.get(
454
+ self.get_document_key(
455
+ doc,
456
+ indices,
457
+ table_name,
458
+ )
459
+ )
451
460
  for doc in ix_docs
452
461
  ]
453
462
  except Exception as e:
@@ -535,7 +544,7 @@ def sync_pipe(
535
544
  def _serialize_indices_docs(_docs):
536
545
  return [
537
546
  {
538
- 'ix': get_document_key(doc, indices),
547
+ 'ix': self.get_document_key(doc, indices),
539
548
  **(
540
549
  {
541
550
  dt_col: doc.get(dt_col, 0)
@@ -594,7 +603,7 @@ def sync_pipe(
594
603
  unseen_docs = unseen_df.to_dict(orient='records') if unseen_df is not None else []
595
604
  unseen_indices_docs = _serialize_indices_docs(unseen_docs)
596
605
  unseen_ix_vals = {
597
- get_document_key(doc, indices, table_name): serialize_document(doc)
606
+ self.get_document_key(doc, indices, table_name): serialize_document(doc)
598
607
  for doc in unseen_docs
599
608
  }
600
609
  for key, val in unseen_ix_vals.items():
@@ -615,7 +624,7 @@ def sync_pipe(
615
624
 
616
625
  update_docs = update_df.to_dict(orient='records') if update_df is not None else []
617
626
  update_ix_docs = {
618
- get_document_key(doc, indices, table_name): doc
627
+ self.get_document_key(doc, indices, table_name): doc
619
628
  for doc in update_docs
620
629
  }
621
630
  existing_docs_data = {
@@ -633,7 +642,7 @@ def sync_pipe(
633
642
  if key not in existing_docs
634
643
  }
635
644
  new_ix_vals = {
636
- get_document_key(doc, indices, table_name): serialize_document(doc)
645
+ self.get_document_key(doc, indices, table_name): serialize_document(doc)
637
646
  for doc in new_update_docs.values()
638
647
  }
639
648
  for key, val in new_ix_vals.items():
@@ -743,8 +752,8 @@ def clear_pipe(
743
752
  table_name = self.quote_table(pipe.target)
744
753
  indices = [col for col in pipe.columns.values() if col]
745
754
  for doc in docs:
746
- set_doc_key = get_document_key(doc, indices)
747
- table_doc_key = get_document_key(doc, indices, table_name)
755
+ set_doc_key = self.get_document_key(doc, indices)
756
+ table_doc_key = self.get_document_key(doc, indices, table_name)
748
757
  try:
749
758
  if dt_col:
750
759
  self.client.zrem(table_name, set_doc_key)
@@ -826,13 +835,15 @@ def get_pipe_rowcount(
826
835
  return 0
827
836
 
828
837
  try:
829
- if begin is None and end is None and params is None:
838
+ if begin is None and end is None and not params:
830
839
  return (
831
840
  self.client.zcard(table_name)
832
841
  if dt_col
833
- else self.client.llen(table_name)
842
+ else self.client.scard(table_name)
834
843
  )
835
- except Exception:
844
+ except Exception as e:
845
+ if debug:
846
+ dprint(f"Failed to get rowcount for {pipe}:\n{e}")
836
847
  return None
837
848
 
838
849
  df = pipe.get_data(begin=begin, end=end, params=params, debug=debug)
@@ -137,6 +137,7 @@ class Pipe:
137
137
  _persist_new_numeric_columns,
138
138
  _persist_new_uuid_columns,
139
139
  _persist_new_bytes_columns,
140
+ _persist_new_geometry_columns,
140
141
  )
141
142
  from ._verify import (
142
143
  verify,
@@ -158,6 +158,7 @@ def sync(
158
158
  'error_callback': error_callback,
159
159
  'sync_chunks': sync_chunks,
160
160
  'chunksize': chunksize,
161
+ 'safe_copy': True,
161
162
  })
162
163
 
163
164
  ### NOTE: Invalidate `_exists` cache before and after syncing.
@@ -268,6 +269,7 @@ def sync(
268
269
  **kw
269
270
  )
270
271
  )
272
+ kw['safe_copy'] = False
271
273
  except Exception as e:
272
274
  get_console().print_exception(
273
275
  suppress=[
@@ -402,6 +404,7 @@ def sync(
402
404
  self._persist_new_numeric_columns(df, debug=debug)
403
405
  self._persist_new_uuid_columns(df, debug=debug)
404
406
  self._persist_new_bytes_columns(df, debug=debug)
407
+ self._persist_new_geometry_columns(df, debug=debug)
405
408
 
406
409
  if debug:
407
410
  dprint(
@@ -1009,7 +1012,7 @@ def _persist_new_numeric_columns(self, df, debug: bool = False) -> SuccessTuple:
1009
1012
 
1010
1013
  self._attributes_sync_time = None
1011
1014
  dtypes = self.parameters.get('dtypes', {})
1012
- dtypes.update({col: 'numeric' for col in numeric_cols})
1015
+ dtypes.update({col: 'numeric' for col in new_numeric_cols})
1013
1016
  self.parameters['dtypes'] = dtypes
1014
1017
  if not self.temporary:
1015
1018
  edit_success, edit_msg = self.edit(interactive=False, debug=debug)
@@ -1034,7 +1037,7 @@ def _persist_new_uuid_columns(self, df, debug: bool = False) -> SuccessTuple:
1034
1037
 
1035
1038
  self._attributes_sync_time = None
1036
1039
  dtypes = self.parameters.get('dtypes', {})
1037
- dtypes.update({col: 'uuid' for col in uuid_cols})
1040
+ dtypes.update({col: 'uuid' for col in new_uuid_cols})
1038
1041
  self.parameters['dtypes'] = dtypes
1039
1042
  if not self.temporary:
1040
1043
  edit_success, edit_msg = self.edit(interactive=False, debug=debug)
@@ -1059,7 +1062,7 @@ def _persist_new_json_columns(self, df, debug: bool = False) -> SuccessTuple:
1059
1062
 
1060
1063
  self._attributes_sync_time = None
1061
1064
  dtypes = self.parameters.get('dtypes', {})
1062
- dtypes.update({col: 'json' for col in json_cols})
1065
+ dtypes.update({col: 'json' for col in new_json_cols})
1063
1066
  self.parameters['dtypes'] = dtypes
1064
1067
 
1065
1068
  if not self.temporary:
@@ -1085,7 +1088,64 @@ def _persist_new_bytes_columns(self, df, debug: bool = False) -> SuccessTuple:
1085
1088
 
1086
1089
  self._attributes_sync_time = None
1087
1090
  dtypes = self.parameters.get('dtypes', {})
1088
- dtypes.update({col: 'bytes' for col in bytes_cols})
1091
+ dtypes.update({col: 'bytes' for col in new_bytes_cols})
1092
+ self.parameters['dtypes'] = dtypes
1093
+
1094
+ if not self.temporary:
1095
+ edit_success, edit_msg = self.edit(interactive=False, debug=debug)
1096
+ if not edit_success:
1097
+ warn(f"Unable to update bytes dtypes for {self}:\n{edit_msg}")
1098
+
1099
+ return edit_success, edit_msg
1100
+
1101
+ return True, "Success"
1102
+
1103
+
1104
+ def _persist_new_geometry_columns(self, df, debug: bool = False) -> SuccessTuple:
1105
+ """
1106
+ Check for new `geometry` columns and update the parameters.
1107
+ """
1108
+ from meerschaum.utils.dataframe import get_geometry_cols
1109
+ geometry_cols_types_srids = get_geometry_cols(df, with_types_srids=True)
1110
+ existing_geometry_cols = [
1111
+ col
1112
+ for col, typ in self.dtypes.items()
1113
+ if typ.startswith('geometry') or typ.startswith('geography')
1114
+ ]
1115
+ new_geometry_cols = [
1116
+ col
1117
+ for col in geometry_cols_types_srids
1118
+ if col not in existing_geometry_cols
1119
+ ]
1120
+ if not new_geometry_cols:
1121
+ return True, "Success"
1122
+
1123
+ self._attributes_sync_time = None
1124
+ dtypes = self.parameters.get('dtypes', {})
1125
+
1126
+ new_cols_types = {}
1127
+ for col, (geometry_type, srid) in geometry_cols_types_srids.items():
1128
+ if col not in new_geometry_cols:
1129
+ continue
1130
+
1131
+ new_dtype = "geometry"
1132
+ modifier = ""
1133
+ if not srid and geometry_type.lower() == 'geometry':
1134
+ new_cols_types[col] = new_dtype
1135
+ continue
1136
+
1137
+ modifier = "["
1138
+ if geometry_type.lower() != 'geometry':
1139
+ modifier += f"{geometry_type}"
1140
+
1141
+ if srid:
1142
+ if modifier != '[':
1143
+ modifier += ", "
1144
+ modifier += f"{srid}"
1145
+ modifier += "]"
1146
+ new_cols_types[col] = f"{new_dtype}{modifier}"
1147
+
1148
+ dtypes.update(new_cols_types)
1089
1149
  self.parameters['dtypes'] = dtypes
1090
1150
 
1091
1151
  if not self.temporary:
@@ -871,7 +871,10 @@ def get_bytes_cols(df: 'pd.DataFrame') -> List[str]:
871
871
  ]
872
872
 
873
873
 
874
- def get_geometry_cols(df: 'pd.DataFrame') -> List[str]:
874
+ def get_geometry_cols(
875
+ df: 'pd.DataFrame',
876
+ with_types_srids: bool = False,
877
+ ) -> Union[List[str], Dict[str, Any]]:
875
878
  """
876
879
  Get the columns which contain shapely objects from a Pandas DataFrame.
877
880
 
@@ -880,9 +883,13 @@ def get_geometry_cols(df: 'pd.DataFrame') -> List[str]:
880
883
  df: pd.DataFrame
881
884
  The DataFrame which may contain bytes strings.
882
885
 
886
+ with_types_srids: bool, default False
887
+ If `True`, return a dictionary mapping columns to geometry types and SRIDs.
888
+
883
889
  Returns
884
890
  -------
885
891
  A list of columns to treat as `geometry`.
892
+ If `with_types_srids`, return a dictionary mapping columns to tuples in the form (type, SRID).
886
893
  """
887
894
  if df is None:
888
895
  return []
@@ -898,7 +905,7 @@ def get_geometry_cols(df: 'pd.DataFrame') -> List[str]:
898
905
  col: df[col].first_valid_index()
899
906
  for col in df.columns
900
907
  }
901
- return [
908
+ geo_cols = [
902
909
  col
903
910
  for col, ix in cols_indices.items()
904
911
  if (
@@ -907,6 +914,31 @@ def get_geometry_cols(df: 'pd.DataFrame') -> List[str]:
907
914
  'shapely' in str(type(df.loc[ix][col]))
908
915
  )
909
916
  ]
917
+ if not with_types_srids:
918
+ return geo_cols
919
+
920
+ gpd = mrsm.attempt_import('geopandas', lazy=False)
921
+ geo_cols_types_srids = {}
922
+ for col in geo_cols:
923
+ try:
924
+ sample_geo_series = gpd.GeoSeries(df[col], crs=None)
925
+ geometry_types = {geom.geom_type for geom in sample_geo_series}
926
+ srid = (
927
+ (
928
+ sample_geo_series.crs.sub_crs_list[0].to_epsg()
929
+ if sample_geo_series.crs.is_compound
930
+ else sample_geo_series.crs.to_epsg()
931
+ )
932
+ if sample_geo_series.crs
933
+ else 0
934
+ )
935
+ geometry_type = list(geometry_types)[0] if len(geometry_types) == 1 else 'geometry'
936
+ except Exception:
937
+ srid = 0
938
+ geometry_type = 'geometry'
939
+ geo_cols_types_srids[col] = (geometry_type, srid)
940
+
941
+ return geo_cols_types_srids
910
942
 
911
943
 
912
944
  def enforce_dtypes(
@@ -1658,6 +1690,8 @@ def to_json(
1658
1690
  orient: str = 'records',
1659
1691
  date_format: str = 'iso',
1660
1692
  date_unit: str = 'us',
1693
+ double_precision: int = 15,
1694
+ geometry_format: str = 'geojson',
1661
1695
  **kwargs: Any
1662
1696
  ) -> str:
1663
1697
  """
@@ -1677,11 +1711,19 @@ def to_json(
1677
1711
  date_unit: str, default 'us'
1678
1712
  The precision of the timestamps.
1679
1713
 
1714
+ double_precision: int, default 15
1715
+ The number of decimal places to use when encoding floating point values (maximum 15).
1716
+
1717
+ geometry_format: str, default 'geojson'
1718
+ The serialization format for geometry data.
1719
+ Accepted values are `geojson`, `wkb_hex`, and `wkt`.
1720
+
1680
1721
  Returns
1681
1722
  -------
1682
1723
  A JSON string.
1683
1724
  """
1684
1725
  import warnings
1726
+ import functools
1685
1727
  from meerschaum.utils.packages import import_pandas
1686
1728
  from meerschaum.utils.dtypes import (
1687
1729
  serialize_bytes,
@@ -1704,10 +1746,16 @@ def to_json(
1704
1746
  with warnings.catch_warnings():
1705
1747
  warnings.simplefilter("ignore")
1706
1748
  for col in geometry_cols:
1707
- df[col] = df[col].apply(serialize_geometry)
1749
+ df[col] = df[col].apply(
1750
+ functools.partial(
1751
+ serialize_geometry,
1752
+ geometry_format=geometry_format,
1753
+ )
1754
+ )
1708
1755
  return df.infer_objects(copy=False).fillna(pd.NA).to_json(
1709
1756
  date_format=date_format,
1710
1757
  date_unit=date_unit,
1758
+ double_precision=double_precision,
1711
1759
  orient=orient,
1712
1760
  **kwargs
1713
1761
  )
@@ -7,6 +7,7 @@ Utility functions for working with data types.
7
7
  """
8
8
 
9
9
  import traceback
10
+ import json
10
11
  import uuid
11
12
  from datetime import timezone, datetime
12
13
  from decimal import Decimal, Context, InvalidOperation, ROUND_HALF_UP
@@ -28,6 +29,7 @@ MRSM_ALIAS_DTYPES: Dict[str, str] = {
28
29
  'guid': 'uuid',
29
30
  'UUID': 'uuid',
30
31
  'geom': 'geometry',
32
+ 'geog': 'geography',
31
33
  }
32
34
  MRSM_PD_DTYPES: Dict[Union[str, None], str] = {
33
35
  'json': 'object',
@@ -76,6 +78,7 @@ def to_pandas_dtype(dtype: str) -> str:
76
78
  return get_pd_type_from_db_type(dtype)
77
79
 
78
80
  from meerschaum.utils.packages import attempt_import
81
+ _ = attempt_import('pyarrow', lazy=False)
79
82
  pandas = attempt_import('pandas', lazy=False)
80
83
 
81
84
  try:
@@ -294,10 +297,21 @@ def attempt_cast_to_geometry(value: Any) -> Any:
294
297
  """
295
298
  Given a value, attempt to coerce it into a `shapely` (`geometry`) object.
296
299
  """
297
- shapely_wkt, shapely_wkb = mrsm.attempt_import('shapely.wkt', 'shapely.wkb', lazy=False)
300
+ shapely, shapely_wkt, shapely_wkb = mrsm.attempt_import(
301
+ 'shapely',
302
+ 'shapely.wkt',
303
+ 'shapely.wkb',
304
+ lazy=False,
305
+ )
298
306
  if 'shapely' in str(type(value)):
299
307
  return value
300
308
 
309
+ if isinstance(value, (dict, list)):
310
+ try:
311
+ return shapely.from_geojson(json.dumps(value))
312
+ except Exception as e:
313
+ return value
314
+
301
315
  value_is_wkt = geometry_is_wkt(value)
302
316
  if value_is_wkt is None:
303
317
  return value
@@ -327,6 +341,9 @@ def geometry_is_wkt(value: Union[str, bytes]) -> Union[bool, None]:
327
341
  Return `None` if `value` should be parsed as neither.
328
342
  """
329
343
  import re
344
+ if not isinstance(value, (str, bytes)):
345
+ return None
346
+
330
347
  if isinstance(value, bytes):
331
348
  return False
332
349
 
@@ -521,7 +538,11 @@ def serialize_bytes(data: bytes) -> str:
521
538
  return base64.b64encode(data).decode('utf-8')
522
539
 
523
540
 
524
- def serialize_geometry(geom: Any, as_wkt: bool = False) -> str:
541
+ def serialize_geometry(
542
+ geom: Any,
543
+ geometry_format: str = 'wkb_hex',
544
+ as_wkt: bool = False,
545
+ ) -> Union[str, Dict[str, Any]]:
525
546
  """
526
547
  Serialize geometry data as a hex-encoded well-known-binary string.
527
548
 
@@ -530,16 +551,22 @@ def serialize_geometry(geom: Any, as_wkt: bool = False) -> str:
530
551
  geom: Any
531
552
  The potential geometry data to be serialized.
532
553
 
533
- as_wkt, bool, default False
534
- If `True`, serialize geometry data as well-known text (WKT)
535
- instead of well-known binary (WKB).
554
+ geometry_format: str, default 'wkb_hex'
555
+ The serialization format for geometry data.
556
+ Accepted formats are `wkb_hex` (well-known binary hex string),
557
+ `wkt` (well-known text), and `geojson`.
536
558
 
537
559
  Returns
538
560
  -------
539
561
  A string containing the geometry data.
540
562
  """
563
+ shapely = mrsm.attempt_import('shapely', lazy=False)
564
+ if geometry_format == 'geojson':
565
+ geojson_str = shapely.to_geojson(geom)
566
+ return json.loads(geojson_str)
567
+
541
568
  if hasattr(geom, 'wkb_hex'):
542
- return geom.wkb_hex if not as_wkt else geom.wkt
569
+ return geom.wkb_hex if geometry_format == 'wkb_hex' else geom.wkt
543
570
 
544
571
  return str(geom)
545
572
 
@@ -711,6 +738,8 @@ def get_geometry_type_srid(
711
738
  ('Point', 4376)
712
739
  """
713
740
  from meerschaum.utils.misc import is_int
741
+ ### NOTE: PostGIS syntax must also be parsed.
742
+ dtype = dtype.replace('(', '[').replace(')', ']')
714
743
  bare_dtype = dtype.split('[', maxsplit=1)[0]
715
744
  modifier = dtype.split(bare_dtype, maxsplit=1)[-1].lstrip('[').rstrip(']')
716
745
  if not modifier: