meerschaum 2.6.5__tar.gz → 2.6.7__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 (276) hide show
  1. {meerschaum-2.6.5/meerschaum.egg-info → meerschaum-2.6.7}/PKG-INFO +2 -1
  2. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/docs/index.py +2 -1
  3. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_version.py +1 -1
  4. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_SQLConnector.py +10 -7
  5. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_pipes.py +11 -7
  6. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/valkey/_pipes.py +58 -11
  7. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_attributes.py +10 -7
  8. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_drop.py +5 -0
  9. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/dataframe.py +7 -3
  10. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/dtypes/__init__.py +2 -2
  11. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/packages/__init__.py +2 -3
  12. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/packages/_packages.py +1 -0
  13. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/sql.py +41 -3
  14. {meerschaum-2.6.5 → meerschaum-2.6.7/meerschaum.egg-info}/PKG-INFO +2 -1
  15. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum.egg-info/requires.txt +1 -0
  16. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_deduplicate.py +9 -15
  17. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_pipe_data.py +0 -10
  18. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_pipes_dtypes.py +13 -12
  19. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_sync.py +45 -95
  20. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_users.py +0 -4
  21. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_verify.py +43 -14
  22. {meerschaum-2.6.5 → meerschaum-2.6.7}/LICENSE +0 -0
  23. {meerschaum-2.6.5 → meerschaum-2.6.7}/NOTICE +0 -0
  24. {meerschaum-2.6.5 → meerschaum-2.6.7}/README.md +0 -0
  25. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/__init__.py +0 -0
  26. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/__main__.py +0 -0
  27. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/__init__.py +0 -0
  28. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/arguments/__init__.py +0 -0
  29. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/arguments/_parse_arguments.py +0 -0
  30. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/arguments/_parser.py +0 -0
  31. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/docs/__init__.py +0 -0
  32. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/entry.py +0 -0
  33. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/gui/__init__.py +0 -0
  34. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/gui/app/__init__.py +0 -0
  35. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/gui/app/_windows.py +0 -0
  36. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/gui/app/actions.py +0 -0
  37. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/gui/app/pipes.py +0 -0
  38. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/shell/Shell.py +0 -0
  39. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/shell/ShellCompleter.py +0 -0
  40. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/shell/ValidAutoSuggest.py +0 -0
  41. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/shell/__init__.py +0 -0
  42. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/shell/resources/__init__.py +0 -0
  43. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/shell/updates.py +0 -0
  44. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/term/TermPageHandler.py +0 -0
  45. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/term/__init__.py +0 -0
  46. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/_internal/term/tools.py +0 -0
  47. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/__init__.py +0 -0
  48. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/api.py +0 -0
  49. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/attach.py +0 -0
  50. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/bootstrap.py +0 -0
  51. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/clear.py +0 -0
  52. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/copy.py +0 -0
  53. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/deduplicate.py +0 -0
  54. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/delete.py +0 -0
  55. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/drop.py +0 -0
  56. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/edit.py +0 -0
  57. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/install.py +0 -0
  58. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/login.py +0 -0
  59. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/os.py +0 -0
  60. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/pause.py +0 -0
  61. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/python.py +0 -0
  62. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/register.py +0 -0
  63. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/reload.py +0 -0
  64. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/restart.py +0 -0
  65. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/setup.py +0 -0
  66. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/sh.py +0 -0
  67. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/show.py +0 -0
  68. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/sql.py +0 -0
  69. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/stack.py +0 -0
  70. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/start.py +0 -0
  71. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/stop.py +0 -0
  72. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/sync.py +0 -0
  73. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/tag.py +0 -0
  74. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/uninstall.py +0 -0
  75. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/upgrade.py +0 -0
  76. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/actions/verify.py +0 -0
  77. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/__init__.py +0 -0
  78. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/_chain.py +0 -0
  79. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/_events.py +0 -0
  80. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/_oauth2.py +0 -0
  81. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/_websockets.py +0 -0
  82. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/__init__.py +0 -0
  83. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/assets/__init__.py +0 -0
  84. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/assets/ansi_up.js +0 -0
  85. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/assets/banner_1920x320.png +0 -0
  86. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/assets/favicon.ico +0 -0
  87. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/assets/logo_48x48.png +0 -0
  88. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/assets/logo_500x500.png +0 -0
  89. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/__init__.py +0 -0
  90. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/custom.py +0 -0
  91. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/dashboard.py +0 -0
  92. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/jobs.py +0 -0
  93. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/login.py +0 -0
  94. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/pipes.py +0 -0
  95. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/plugins.py +0 -0
  96. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/callbacks/register.py +0 -0
  97. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/components.py +0 -0
  98. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/connectors.py +0 -0
  99. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/graphs.py +0 -0
  100. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/jobs.py +0 -0
  101. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/keys.py +0 -0
  102. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/__init__.py +0 -0
  103. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/dashboard.py +0 -0
  104. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/error.py +0 -0
  105. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/job.py +0 -0
  106. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/login.py +0 -0
  107. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/pipes.py +0 -0
  108. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/plugins.py +0 -0
  109. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pages/register.py +0 -0
  110. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/pipes.py +0 -0
  111. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/plugins.py +0 -0
  112. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/sessions.py +0 -0
  113. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/sync.py +0 -0
  114. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/users.py +0 -0
  115. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/websockets.py +0 -0
  116. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/dash/webterm.py +0 -0
  117. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/models/__init__.py +0 -0
  118. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/models/_interfaces.py +0 -0
  119. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/models/_locations.py +0 -0
  120. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/models/_metrics.py +0 -0
  121. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/models/_pipes.py +0 -0
  122. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/__init__.py +0 -0
  123. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/__init__.py +0 -0
  124. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/css/__init__.py +0 -0
  125. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/css/bootstrap.min.css +0 -0
  126. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/css/dash.css +0 -0
  127. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/css/dbc_dark.css +0 -0
  128. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/css/styles.css +0 -0
  129. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/css/xterm.css +0 -0
  130. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/ico/__init__.py +0 -0
  131. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/ico/logo.ico +0 -0
  132. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/js/__init__.py +0 -0
  133. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/js/action_button.js +0 -0
  134. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/js/main.js +0 -0
  135. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/js/terminado.js +0 -0
  136. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/js/xterm.js +0 -0
  137. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/static/png/__init__.py +0 -0
  138. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/templates/__init__.py +0 -0
  139. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/templates/index.html +0 -0
  140. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/templates/old_index.html +0 -0
  141. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/templates/secret.html +0 -0
  142. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/resources/templates/termpage.html +0 -0
  143. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/__init__.py +0 -0
  144. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_actions.py +0 -0
  145. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_connectors.py +0 -0
  146. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_index.py +0 -0
  147. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_jobs.py +0 -0
  148. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_login.py +0 -0
  149. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_misc.py +0 -0
  150. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_pipes.py +0 -0
  151. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_plugins.py +0 -0
  152. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_users.py +0 -0
  153. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_version.py +0 -0
  154. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/routes/_webterm.py +0 -0
  155. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/api/tables/__init__.py +0 -0
  156. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/__init__.py +0 -0
  157. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_dash.py +0 -0
  158. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_default.py +0 -0
  159. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_edit.py +0 -0
  160. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_environment.py +0 -0
  161. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_formatting.py +0 -0
  162. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_jobs.py +0 -0
  163. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_patch.py +0 -0
  164. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_paths.py +0 -0
  165. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_preprocess.py +0 -0
  166. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_read_config.py +0 -0
  167. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_shell.py +0 -0
  168. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/_sync.py +0 -0
  169. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/paths.py +0 -0
  170. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/resources/__init__.py +0 -0
  171. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/stack/__init__.py +0 -0
  172. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/stack/grafana/__init__.py +0 -0
  173. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/stack/mosquitto/__init__.py +0 -0
  174. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/stack/mosquitto/resources/__init__.py +0 -0
  175. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/stack/resources/__init__.py +0 -0
  176. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/config/static/__init__.py +0 -0
  177. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/_Connector.py +0 -0
  178. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/__init__.py +0 -0
  179. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_APIConnector.py +0 -0
  180. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/__init__.py +0 -0
  181. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_actions.py +0 -0
  182. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_fetch.py +0 -0
  183. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_jobs.py +0 -0
  184. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_login.py +0 -0
  185. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_misc.py +0 -0
  186. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_pipes.py +0 -0
  187. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_plugins.py +0 -0
  188. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_request.py +0 -0
  189. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_uri.py +0 -0
  190. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/api/_users.py +0 -0
  191. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/parse.py +0 -0
  192. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/plugin/PluginConnector.py +0 -0
  193. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/plugin/__init__.py +0 -0
  194. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/poll.py +0 -0
  195. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/__init__.py +0 -0
  196. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_cli.py +0 -0
  197. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_create_engine.py +0 -0
  198. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_fetch.py +0 -0
  199. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_instance.py +0 -0
  200. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_plugins.py +0 -0
  201. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_sql.py +0 -0
  202. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_uri.py +0 -0
  203. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/_users.py +0 -0
  204. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/tables/__init__.py +0 -0
  205. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/tables/types.py +0 -0
  206. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/sql/tools.py +0 -0
  207. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/valkey/_ValkeyConnector.py +0 -0
  208. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/valkey/__init__.py +0 -0
  209. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/valkey/_fetch.py +0 -0
  210. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/valkey/_plugins.py +0 -0
  211. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/connectors/valkey/_users.py +0 -0
  212. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/__init__.py +0 -0
  213. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_bootstrap.py +0 -0
  214. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_clear.py +0 -0
  215. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_copy.py +0 -0
  216. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_data.py +0 -0
  217. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_deduplicate.py +0 -0
  218. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_delete.py +0 -0
  219. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_dtypes.py +0 -0
  220. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_edit.py +0 -0
  221. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_fetch.py +0 -0
  222. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_register.py +0 -0
  223. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_show.py +0 -0
  224. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_sync.py +0 -0
  225. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Pipe/_verify.py +0 -0
  226. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/Plugin/__init__.py +0 -0
  227. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/User/_User.py +0 -0
  228. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/User/__init__.py +0 -0
  229. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/core/__init__.py +0 -0
  230. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/jobs/_Executor.py +0 -0
  231. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/jobs/_Job.py +0 -0
  232. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/jobs/__init__.py +0 -0
  233. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/jobs/systemd.py +0 -0
  234. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/plugins/_Plugin.py +0 -0
  235. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/plugins/__init__.py +0 -0
  236. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/plugins/bootstrap.py +0 -0
  237. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/__init__.py +0 -0
  238. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/_get_pipes.py +0 -0
  239. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/daemon/Daemon.py +0 -0
  240. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -0
  241. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/daemon/RotatingFile.py +0 -0
  242. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/daemon/StdinFile.py +0 -0
  243. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/daemon/__init__.py +0 -0
  244. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/daemon/_names.py +0 -0
  245. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/debug.py +0 -0
  246. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/dtypes/sql.py +0 -0
  247. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/formatting/__init__.py +0 -0
  248. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/formatting/_jobs.py +0 -0
  249. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/formatting/_pipes.py +0 -0
  250. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/formatting/_pprint.py +0 -0
  251. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/formatting/_shell.py +0 -0
  252. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/interactive.py +0 -0
  253. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/misc.py +0 -0
  254. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/networking.py +0 -0
  255. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/packages/lazy_loader.py +0 -0
  256. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/pool.py +0 -0
  257. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/process.py +0 -0
  258. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/prompt.py +0 -0
  259. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/schedule.py +0 -0
  260. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/threading.py +0 -0
  261. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/typing.py +0 -0
  262. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/venv/_Venv.py +0 -0
  263. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/venv/__init__.py +0 -0
  264. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/warnings.py +0 -0
  265. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum/utils/yaml.py +0 -0
  266. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum.egg-info/SOURCES.txt +0 -0
  267. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum.egg-info/dependency_links.txt +0 -0
  268. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum.egg-info/entry_points.txt +0 -0
  269. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum.egg-info/top_level.txt +0 -0
  270. {meerschaum-2.6.5 → meerschaum-2.6.7}/meerschaum.egg-info/zip-safe +0 -0
  271. {meerschaum-2.6.5 → meerschaum-2.6.7}/setup.cfg +0 -0
  272. {meerschaum-2.6.5 → meerschaum-2.6.7}/setup.py +0 -0
  273. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_actions.py +0 -0
  274. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_arguments.py +0 -0
  275. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_jobs.py +0 -0
  276. {meerschaum-2.6.5 → meerschaum-2.6.7}/tests/test_sql.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: meerschaum
3
- Version: 2.6.5
3
+ Version: 2.6.7
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Home-page: https://meerschaum.io
6
6
  Author: Bennett Meares
@@ -101,6 +101,7 @@ Requires-Dist: pytest>=6.2.2; extra == "dev-tools"
101
101
  Requires-Dist: pytest-xdist>=3.2.1; extra == "dev-tools"
102
102
  Requires-Dist: heartrate>=0.2.1; extra == "dev-tools"
103
103
  Requires-Dist: build>=1.2.1; extra == "dev-tools"
104
+ Requires-Dist: attrs>=24.2.0; extra == "dev-tools"
104
105
  Provides-Extra: setup
105
106
  Provides-Extra: docs
106
107
  Requires-Dist: mkdocs>=1.1.2; extra == "docs"
@@ -741,10 +741,11 @@ def init_dash(dash_app):
741
741
  <li><code>meerschaum.utils.sql.get_null_replacement()</code></li>
742
742
  <li><code>meerschaum.utils.sql.get_db_version()</code></li>
743
743
  <li><code>meerschaum.utils.sql.get_rename_table_queries()</code></li>
744
- <li><code>meerschaum.utils.sql.get_create_table_query()</code></li>
744
+ <li><code>meerschaum.utils.sql.get_create_table_queries()</code></li>
745
745
  <li><code>meerschaum.utils.sql.wrap_query_with_cte()</code></li>
746
746
  <li><code>meerschaum.utils.sql.format_cte_subquery()</code></li>
747
747
  <li><code>meerschaum.utils.sql.session_execute()</code></li>
748
+ <li><code>meerschaum.utils.sql.get_reset_autoincrement_queries()</code></li>
748
749
  </ul>
749
750
  </details>
750
751
  </ul>
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.6.5"
5
+ __version__ = "2.6.7"
@@ -11,7 +11,7 @@ import meerschaum as mrsm
11
11
  from meerschaum.utils.typing import Optional, Any, Union
12
12
 
13
13
  from meerschaum.connectors import Connector
14
- from meerschaum.utils.warnings import error
14
+ from meerschaum.utils.warnings import error, warn
15
15
 
16
16
 
17
17
  class SQLConnector(Connector):
@@ -212,7 +212,6 @@ class SQLConnector(Connector):
212
212
 
213
213
  if connect:
214
214
  if not self.test_connection(debug=debug):
215
- from meerschaum.utils.warnings import warn
216
215
  warn(f"Failed to connect with connector '{self}'!", stack=False)
217
216
 
218
217
  @property
@@ -230,8 +229,11 @@ class SQLConnector(Connector):
230
229
 
231
230
  @property
232
231
  def engine(self):
233
- import os, threading
234
- ### build the sqlalchemy engine
232
+ """
233
+ Return the SQLAlchemy engine connected to the configured database.
234
+ """
235
+ import os
236
+ import threading
235
237
  if '_engine' not in self.__dict__:
236
238
  self._engine, self._engine_str = self.create_engine(include_uri=True)
237
239
 
@@ -242,13 +244,14 @@ class SQLConnector(Connector):
242
244
  if not same_process:
243
245
  self._pid = os.getpid()
244
246
  self._thread = threading.current_thread()
245
- from meerschaum.utils.warnings import warn
246
- warn(f"Different PID detected. Disposing of connections...")
247
+ warn("Different PID detected. Disposing of connections...")
247
248
  self._engine.dispose()
248
249
 
249
250
  ### handle different threads
250
251
  if not same_thread:
251
- pass
252
+ if self.flavor == 'duckdb':
253
+ warn("Different thread detected.")
254
+ self._engine.dispose()
252
255
 
253
256
  return self._engine
254
257
 
@@ -1349,9 +1349,9 @@ def create_pipe_table_from_df(
1349
1349
  for col, typ in df.dtypes.items()
1350
1350
  },
1351
1351
  **{
1352
- col: 'int'
1352
+ col: str(df.dtypes.get(col, 'int'))
1353
1353
  for col_ix, col in pipe.columns.items()
1354
- if col_ix != 'primary'
1354
+ if col and col_ix != 'primary'
1355
1355
  },
1356
1356
  **{
1357
1357
  col: 'uuid'
@@ -1696,7 +1696,9 @@ def sync_pipe(
1696
1696
  )
1697
1697
  for col, typ in update_df.dtypes.items()
1698
1698
  }
1699
- temp_pipe.__dict__['_columns_types_timestamp'] = time.perf_counter()
1699
+ now_ts = time.perf_counter()
1700
+ temp_pipe.__dict__['_columns_types_timestamp'] = now_ts
1701
+ temp_pipe.__dict__['_skip_check_indices'] = True
1700
1702
  temp_success, temp_msg = temp_pipe.sync(update_df, check_existing=False, debug=debug)
1701
1703
  if not temp_success:
1702
1704
  return temp_success, temp_msg
@@ -1867,6 +1869,7 @@ def sync_pipe_inplace(
1867
1869
  )
1868
1870
  pipe_name = sql_item_name(pipe.target, self.flavor, self.get_pipe_schema(pipe))
1869
1871
  upsert = pipe.parameters.get('upsert', False) and f'{self.flavor}-upsert' in update_queries
1872
+ static = pipe.parameters.get('static', False)
1870
1873
  database = getattr(self, 'database', self.parse_uri(self.URI).get('database', None))
1871
1874
  primary_key = pipe.columns.get('primary', None)
1872
1875
  autoincrement = pipe.parameters.get('autoincrement', False)
@@ -1944,7 +1947,7 @@ def sync_pipe_inplace(
1944
1947
  schema=internal_schema,
1945
1948
  database=database,
1946
1949
  debug=debug,
1947
- )
1950
+ ) if not static else pipe.get_columns_types(debug=debug)
1948
1951
  if not new_cols_types:
1949
1952
  return False, f"Failed to get new columns for {pipe}."
1950
1953
 
@@ -2049,7 +2052,7 @@ def sync_pipe_inplace(
2049
2052
  schema=internal_schema,
2050
2053
  database=database,
2051
2054
  debug=debug,
2052
- ) if not upsert else new_cols_types
2055
+ ) if not (upsert or static) else new_cols_types
2053
2056
 
2054
2057
  common_cols = [col for col in new_cols if col in backtrack_cols_types]
2055
2058
  on_cols = {
@@ -2123,7 +2126,7 @@ def sync_pipe_inplace(
2123
2126
  schema=internal_schema,
2124
2127
  database=database,
2125
2128
  debug=debug,
2126
- ) if not upsert else new_cols_types
2129
+ ) if not (upsert or static) else new_cols_types
2127
2130
 
2128
2131
  ### This is a weird bug on SQLite.
2129
2132
  ### Sometimes the backtrack dtypes are all empty strings.
@@ -2812,12 +2815,13 @@ def get_pipe_columns_indices(
2812
2815
  pipe: mrsm.Pipe
2813
2816
  The pipe to be queried against.
2814
2817
 
2815
-
2816
2818
  Returns
2817
2819
  -------
2818
2820
  A dictionary mapping columns names to lists of dictionaries.
2819
2821
  The dictionaries in the lists contain the name and type of the indices.
2820
2822
  """
2823
+ if pipe.__dict__.get('_skip_check_indices', False):
2824
+ return {}
2821
2825
  from meerschaum.utils.sql import get_table_cols_indices
2822
2826
  return get_table_cols_indices(
2823
2827
  pipe.target,
@@ -305,6 +305,14 @@ def drop_pipe(
305
305
  -------
306
306
  A `SuccessTuple` indicating success.
307
307
  """
308
+ for chunk_begin, chunk_end in pipe.get_chunk_bounds(debug=debug):
309
+ clear_chunk_success, clear_chunk_msg = pipe.clear(
310
+ begin=chunk_begin,
311
+ end=chunk_end,
312
+ debug=debug,
313
+ )
314
+ if not clear_chunk_success:
315
+ return clear_chunk_success, clear_chunk_msg
308
316
  try:
309
317
  self.drop_table(pipe.target, debug=debug)
310
318
  except Exception as e:
@@ -547,7 +555,7 @@ def sync_pipe(
547
555
  new_dtypes[col] = 'string'
548
556
  df[col] = df[col].astype('string')
549
557
 
550
- if new_dtypes and not static:
558
+ if new_dtypes and (not static or not valkey_dtypes):
551
559
  valkey_dtypes.update(new_dtypes)
552
560
  if 'valkey' not in pipe.parameters:
553
561
  pipe.parameters['valkey'] = {}
@@ -560,19 +568,19 @@ def sync_pipe(
560
568
  unseen_df, update_df, delta_df = (
561
569
  pipe.filter_existing(df, include_unchanged_columns=True, debug=debug)
562
570
  if check_existing and not upsert
563
- else (df, None, df)
571
+ else (None, df, df)
564
572
  )
565
573
  num_insert = len(unseen_df) if unseen_df is not None else 0
566
574
  num_update = len(update_df) if update_df is not None else 0
567
575
  msg = (
568
576
  f"Inserted {num_insert}, updated {num_update} rows."
569
577
  if not upsert
570
- else f"Upserted {num_insert} rows."
578
+ else f"Upserted {num_update} rows."
571
579
  )
572
580
  if len(delta_df) == 0:
573
581
  return True, msg
574
582
 
575
- unseen_docs = unseen_df.to_dict(orient='records')
583
+ unseen_docs = unseen_df.to_dict(orient='records') if unseen_df is not None else []
576
584
  unseen_indices_docs = _serialize_indices_docs(unseen_docs)
577
585
  unseen_ix_vals = {
578
586
  get_document_key(doc, indices, table_name): serialize_document(doc)
@@ -599,11 +607,53 @@ def sync_pipe(
599
607
  get_document_key(doc, indices, table_name): doc
600
608
  for doc in update_docs
601
609
  }
602
- for key, doc in update_ix_docs.items():
610
+ existing_docs_data = {
611
+ key: self.get(key)
612
+ for key in update_ix_docs
613
+ } if pipe.exists(debug=debug) else {}
614
+ existing_docs = {
615
+ key: json.loads(data)
616
+ for key, data in existing_docs_data.items()
617
+ if data
618
+ }
619
+ new_update_docs = {
620
+ key: doc
621
+ for key, doc in update_ix_docs.items()
622
+ if key not in existing_docs
623
+ }
624
+ new_ix_vals = {
625
+ get_document_key(doc, indices, table_name): serialize_document(doc)
626
+ for doc in new_update_docs.values()
627
+ }
628
+ for key, val in new_ix_vals.items():
603
629
  try:
604
- old_doc = json.loads(self.get(key))
605
- old_doc.update(doc)
606
- self.set(key, serialize_document(old_doc))
630
+ self.set(key, val)
631
+ except Exception as e:
632
+ return False, f"Failed to set keys for {pipe}:\n{e}"
633
+
634
+ old_update_docs = {
635
+ key: {
636
+ **existing_docs[key],
637
+ **doc
638
+ }
639
+ for key, doc in update_ix_docs.items()
640
+ if key in existing_docs
641
+ }
642
+ new_indices_docs = _serialize_indices_docs([doc for doc in new_update_docs.values()])
643
+ try:
644
+ if new_indices_docs:
645
+ self.push_docs(
646
+ new_indices_docs,
647
+ pipe.target,
648
+ datetime_column=dt_col,
649
+ debug=debug,
650
+ )
651
+ except Exception as e:
652
+ return False, f"Failed to upsert '{pipe.target}':\n{e}"
653
+
654
+ for key, doc in old_update_docs.items():
655
+ try:
656
+ self.set(key, serialize_document(doc))
607
657
  except Exception as e:
608
658
  return False, f"Failed to set keys for {pipe}:\n{e}"
609
659
 
@@ -667,9 +717,6 @@ def clear_pipe(
667
717
  -------
668
718
  A `SuccessTuple` indicating success.
669
719
  """
670
- if begin is None and end is None and params is None:
671
- return self.drop_pipe(pipe, debug=debug)
672
-
673
720
  dt_col = pipe.columns.get('datetime', None)
674
721
 
675
722
  existing_df = pipe.get_data(
@@ -85,7 +85,7 @@ def columns(self) -> Union[Dict[str, str], None]:
85
85
  if not isinstance(cols, dict):
86
86
  cols = {}
87
87
  self.parameters['columns'] = cols
88
- return cols
88
+ return {col_ix: col for col_ix, col in cols.items() if col}
89
89
 
90
90
 
91
91
  @columns.setter
@@ -127,11 +127,11 @@ def indices(self) -> Union[Dict[str, Union[str, List[str]]], None]:
127
127
  ) + [
128
128
  col
129
129
  for col_ix, col in _columns.items()
130
- if col_ix != 'datetime'
130
+ if col and col_ix != 'datetime'
131
131
  ]))
132
132
  return {
133
133
  **({'unique': unique_cols} if len(unique_cols) > 1 else {}),
134
- **_columns,
134
+ **{col_ix: col for col_ix, col in _columns.items() if col},
135
135
  **_indices
136
136
  }
137
137
 
@@ -371,8 +371,7 @@ def get_columns_types(
371
371
 
372
372
  now = time.perf_counter()
373
373
  cache_seconds = STATIC_CONFIG['pipes']['static_schema_cache_seconds']
374
- static = self.parameters.get('static', False)
375
- if not static:
374
+ if not self.static:
376
375
  refresh = True
377
376
  if refresh:
378
377
  _ = self.__dict__.pop('_columns_types_timestamp', None)
@@ -416,7 +415,11 @@ def get_columns_indices(
416
415
  from meerschaum.utils.warnings import dprint
417
416
 
418
417
  now = time.perf_counter()
419
- exists_timeout_seconds = STATIC_CONFIG['pipes']['exists_timeout_seconds']
418
+ cache_seconds = (
419
+ STATIC_CONFIG['pipes']['static_schema_cache_seconds']
420
+ if self.static
421
+ else STATIC_CONFIG['pipes']['exists_timeout_seconds']
422
+ )
420
423
  if refresh:
421
424
  _ = self.__dict__.pop('_columns_indices_timestamp', None)
422
425
  _ = self.__dict__.pop('_columns_indices', None)
@@ -425,7 +428,7 @@ def get_columns_indices(
425
428
  columns_indices_timestamp = self.__dict__.get('_columns_indices_timestamp', None)
426
429
  if columns_indices_timestamp is not None:
427
430
  delta = now - columns_indices_timestamp
428
- if delta < exists_timeout_seconds:
431
+ if delta < cache_seconds:
429
432
  if debug:
430
433
  dprint(
431
434
  f"Returning cached `columns_indices` for {self} "
@@ -9,6 +9,7 @@ Drop a Pipe's table but keep its registration
9
9
  from __future__ import annotations
10
10
  from meerschaum.utils.typing import SuccessTuple, Any
11
11
 
12
+
12
13
  def drop(
13
14
  self,
14
15
  debug: bool = False,
@@ -39,4 +40,8 @@ def drop(
39
40
 
40
41
  with Venv(get_connector_plugin(self.instance_connector)):
41
42
  result = self.instance_connector.drop_pipe(self, debug=debug, **kw)
43
+
44
+ _ = self.__dict__.pop('_exists', None)
45
+ _ = self.__dict__.pop('_exists_timestamp', None)
46
+
42
47
  return result
@@ -234,10 +234,13 @@ def filter_unseen_df(
234
234
  cast_dt_cols = True
235
235
  try:
236
236
  for col, typ in dt_dtypes.items():
237
+ strip_utc = (
238
+ (dtypes or {}).get(col, 'datetime') == 'datetime64[ns]'
239
+ )
237
240
  if col in old_df.columns:
238
- old_df[col] = coerce_timezone(old_df[col])
241
+ old_df[col] = coerce_timezone(old_df[col], strip_utc=strip_utc)
239
242
  if col in new_df.columns:
240
- new_df[col] = coerce_timezone(new_df[col])
243
+ new_df[col] = coerce_timezone(new_df[col], strip_utc=strip_utc)
241
244
  cast_dt_cols = False
242
245
  except Exception as e:
243
246
  warn(f"Could not cast datetime columns:\n{e}")
@@ -1284,7 +1287,8 @@ def query_df(
1284
1287
  if debug:
1285
1288
  dprint(f"Casting column '{datetime_column}' to UTC...")
1286
1289
  df[datetime_column] = coerce_timezone(df[datetime_column], strip_utc=False)
1287
- dprint(f"Using datetime bounds:\n{begin=}\n{end=}")
1290
+ if debug:
1291
+ dprint(f"Using datetime bounds:\n{begin=}\n{end=}")
1288
1292
 
1289
1293
  in_ex_params = get_in_ex_params(params)
1290
1294
 
@@ -270,9 +270,9 @@ def coerce_timezone(
270
270
  pandas = mrsm.attempt_import('pandas')
271
271
  dd = mrsm.attempt_import('dask.dataframe') if is_dask else None
272
272
  dt_series = (
273
- pandas.to_datetime(dt, utc=True)
273
+ pandas.to_datetime(dt, utc=True, format='ISO8601')
274
274
  if dd is None
275
- else dd.to_datetime(dt, utc=True)
275
+ else dd.to_datetime(dt, utc=True, format='ISO8601')
276
276
  )
277
277
  if strip_utc:
278
278
  dt_series = dt_series.apply(lambda x: x.replace(tzinfo=None))
@@ -1467,7 +1467,6 @@ def import_pandas(
1467
1467
  """
1468
1468
  Quality-of-life function to attempt to import the configured version of `pandas`.
1469
1469
  """
1470
- import sys
1471
1470
  pandas_module_name = pandas_name()
1472
1471
  global emitted_pandas_warning
1473
1472
 
@@ -1482,11 +1481,11 @@ def import_pandas(
1482
1481
  + f"'{pandas_module_name}'"
1483
1482
  + "\n Features may not work as expected."
1484
1483
  ),
1485
- stack = False,
1484
+ stack=False,
1486
1485
  )
1487
1486
 
1488
1487
  pytz = attempt_import('pytz', debug=debug, lazy=False, **kw)
1489
- pandas = attempt_import('pandas', debug=debug, lazy=False, **kw)
1488
+ pandas, pyarrow = attempt_import('pandas', 'pyarrow', debug=debug, lazy=False, **kw)
1490
1489
  pd = attempt_import(pandas_module_name, debug=debug, lazy=lazy, **kw)
1491
1490
  return pd
1492
1491
 
@@ -103,6 +103,7 @@ packages: Dict[str, Dict[str, str]] = {
103
103
  'pytest_xdist' : 'pytest-xdist>=3.2.1',
104
104
  'heartrate' : 'heartrate>=0.2.1',
105
105
  'build' : 'build>=1.2.1',
106
+ 'attrs' : 'attrs>=24.2.0',
106
107
  },
107
108
  'setup': {
108
109
  },
@@ -87,9 +87,11 @@ update_queries = {
87
87
  WHERE {date_bounds_subquery}
88
88
  """,
89
89
  'mysql-upsert': """
90
- REPLACE INTO {target_table_name} ({patch_cols_str})
90
+ INSERT {ignore}INTO {target_table_name} ({patch_cols_str})
91
91
  SELECT {patch_cols_str}
92
92
  FROM {patch_table_name}
93
+ {on_duplicate_key_update}
94
+ {cols_equal_values}
93
95
  """,
94
96
  'mariadb': """
95
97
  UPDATE {target_table_name} AS f
@@ -99,9 +101,11 @@ update_queries = {
99
101
  WHERE {date_bounds_subquery}
100
102
  """,
101
103
  'mariadb-upsert': """
102
- REPLACE INTO {target_table_name} ({patch_cols_str})
104
+ INSERT {ignore}INTO {target_table_name} ({patch_cols_str})
103
105
  SELECT {patch_cols_str}
104
106
  FROM {patch_table_name}
107
+ {on_duplicate_key_update}
108
+ {cols_equal_values}
105
109
  """,
106
110
  'mssql': """
107
111
  MERGE {target_table_name} f
@@ -1578,6 +1582,19 @@ def get_update_queries(
1578
1582
  f" UPDATE {sets_subquery('', 'p.')}"
1579
1583
  )
1580
1584
 
1585
+ cols_equal_values = '\n,'.join(
1586
+ [
1587
+ f"{sql_item_name(c_name, flavor)} = VALUES({sql_item_name(c_name, flavor)})"
1588
+ for c_name, c_type in value_cols
1589
+ ]
1590
+ )
1591
+ on_duplicate_key_update = (
1592
+ "ON DUPLICATE KEY UPDATE"
1593
+ if value_cols
1594
+ else ""
1595
+ )
1596
+ ignore = "IGNORE " if not value_cols else ""
1597
+
1581
1598
  return [
1582
1599
  base_query.format(
1583
1600
  sets_subquery_none=sets_subquery('', 'p.'),
@@ -1594,6 +1611,9 @@ def get_update_queries(
1594
1611
  coalesce_join_cols_str=coalesce_join_cols_str,
1595
1612
  update_or_nothing=update_or_nothing,
1596
1613
  when_matched_update_sets_subquery_none=when_matched_update_sets_subquery_none,
1614
+ cols_equal_values=cols_equal_values,
1615
+ on_duplicate_key_update=on_duplicate_key_update,
1616
+ ignore=ignore,
1597
1617
  )
1598
1618
  for base_query in base_queries
1599
1619
  ]
@@ -2179,7 +2199,25 @@ def get_reset_autoincrement_queries(
2179
2199
  debug: bool = False,
2180
2200
  ) -> List[str]:
2181
2201
  """
2182
- Return a list of queries to reset a table's auto-increment counter.
2202
+ Return a list of queries to reset a table's auto-increment counter to the next largest value.
2203
+
2204
+ Parameters
2205
+ ----------
2206
+ table: str
2207
+ The name of the table on which the auto-incrementing column exists.
2208
+
2209
+ column: str
2210
+ The name of the auto-incrementing column.
2211
+
2212
+ connector: mrsm.connectors.SQLConnector
2213
+ The SQLConnector to the database on which the table exists.
2214
+
2215
+ schema: Optional[str], default None
2216
+ The schema of the table. Defaults to `connector.schema`.
2217
+
2218
+ Returns
2219
+ -------
2220
+ A list of queries to be executed to reset the auto-incrementing column.
2183
2221
  """
2184
2222
  if not table_exists(table, connector, schema=schema, debug=debug):
2185
2223
  return []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: meerschaum
3
- Version: 2.6.5
3
+ Version: 2.6.7
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Home-page: https://meerschaum.io
6
6
  Author: Bennett Meares
@@ -101,6 +101,7 @@ Requires-Dist: pytest>=6.2.2; extra == "dev-tools"
101
101
  Requires-Dist: pytest-xdist>=3.2.1; extra == "dev-tools"
102
102
  Requires-Dist: heartrate>=0.2.1; extra == "dev-tools"
103
103
  Requires-Dist: build>=1.2.1; extra == "dev-tools"
104
+ Requires-Dist: attrs>=24.2.0; extra == "dev-tools"
104
105
  Provides-Extra: setup
105
106
  Provides-Extra: docs
106
107
  Requires-Dist: mkdocs>=1.1.2; extra == "docs"
@@ -125,6 +125,7 @@ pytest>=6.2.2
125
125
  pytest-xdist>=3.2.1
126
126
  heartrate>=0.2.1
127
127
  build>=1.2.1
128
+ attrs>=24.2.0
128
129
 
129
130
  [docs]
130
131
  mkdocs>=1.1.2
@@ -6,28 +6,22 @@
6
6
  Test pipe deduplication syncs.
7
7
  """
8
8
 
9
- import pytest
10
9
  import json
11
10
  from datetime import datetime, timedelta
11
+
12
+ import pytest
13
+
14
+ import meerschaum as mrsm
15
+
12
16
  from tests import debug
13
- from tests.pipes import all_pipes, stress_pipes, remote_pipes
14
17
  from tests.connectors import conns, get_flavors
15
- from tests.test_users import test_register_user
16
- import meerschaum as mrsm
17
- from meerschaum import Pipe
18
- from meerschaum.actions import actions
19
18
 
20
- @pytest.fixture(autouse=True)
21
- def run_before_and_after(flavor: str):
22
- test_register_user(flavor)
23
- yield
24
19
 
25
20
  @pytest.mark.parametrize("flavor", get_flavors())
26
21
  def test_deduplicate_default(flavor: str):
27
22
  """
28
23
  Test that verification will fill any backtracked docs.
29
24
  """
30
- import pandas as pd
31
25
  from meerschaum.utils.sql import sql_item_name
32
26
  from meerschaum.utils.dataframe import parse_df_datetimes
33
27
  conn = conns[flavor]
@@ -70,16 +64,16 @@ def test_deduplicate_without_instance_method(flavor: str):
70
64
  """
71
65
  Test that verification will fill any backtracked docs.
72
66
  """
73
- import pandas as pd
74
- from meerschaum.utils.sql import sql_item_name
75
67
  from meerschaum.utils.dataframe import parse_df_datetimes
76
68
  conn = conns[flavor]
77
69
  if conn.type != 'sql':
78
70
  return
71
+ pipe = mrsm.Pipe('test', 'deduplicate', 'chunked', instance=conn)
72
+ pipe.delete()
79
73
  pipe = mrsm.Pipe(
80
74
  'test', 'deduplicate', 'chunked',
81
- instance = conn,
82
- columns = {
75
+ instance=conn,
76
+ columns={
83
77
  'datetime': 'datetime',
84
78
  'id': 'id',
85
79
  }
@@ -10,16 +10,6 @@ from meerschaum import Pipe
10
10
 
11
11
  from tests.connectors import conns, get_flavors
12
12
  from tests import debug
13
- from tests.test_users import test_register_user as _test_register_user
14
-
15
-
16
- @pytest.fixture(autouse=True)
17
- def run_before_and_after(flavor: str):
18
- """
19
- Ensure the test user is registered before running tests.
20
- """
21
- _test_register_user(flavor)
22
- yield
23
13
 
24
14
 
25
15
  @pytest.mark.parametrize("flavor", get_flavors())