meerschaum 2.4.13__tar.gz → 2.5.0__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.4.13/meerschaum.egg-info → meerschaum-2.5.0}/PKG-INFO +9 -13
  2. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/upgrade.py +3 -2
  3. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_version.py +1 -1
  4. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_create_engine.py +8 -3
  5. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_fetch.py +2 -2
  6. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_instance.py +3 -3
  7. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_pipes.py +18 -13
  8. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_sql.py +59 -50
  9. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/__init__.py +23 -1
  10. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_attributes.py +96 -14
  11. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/dataframe.py +17 -5
  12. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/packages/__init__.py +40 -22
  13. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/packages/_packages.py +24 -8
  14. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/schedule.py +9 -5
  15. {meerschaum-2.4.13 → meerschaum-2.5.0/meerschaum.egg-info}/PKG-INFO +9 -13
  16. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum.egg-info/requires.txt +8 -12
  17. {meerschaum-2.4.13 → meerschaum-2.5.0}/setup.py +2 -0
  18. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_pipe_data.py +10 -0
  19. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_sync.py +3 -1
  20. {meerschaum-2.4.13 → meerschaum-2.5.0}/LICENSE +0 -0
  21. {meerschaum-2.4.13 → meerschaum-2.5.0}/NOTICE +0 -0
  22. {meerschaum-2.4.13 → meerschaum-2.5.0}/README.md +0 -0
  23. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/__init__.py +0 -0
  24. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/__main__.py +0 -0
  25. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/__init__.py +0 -0
  26. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/arguments/__init__.py +0 -0
  27. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/arguments/_parse_arguments.py +0 -0
  28. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/arguments/_parser.py +0 -0
  29. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/docs/__init__.py +0 -0
  30. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/docs/index.py +0 -0
  31. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/entry.py +0 -0
  32. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/gui/__init__.py +0 -0
  33. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/gui/app/__init__.py +0 -0
  34. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/gui/app/_windows.py +0 -0
  35. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/gui/app/actions.py +0 -0
  36. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/gui/app/pipes.py +0 -0
  37. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/shell/Shell.py +0 -0
  38. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/shell/ShellCompleter.py +0 -0
  39. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/shell/ValidAutoSuggest.py +0 -0
  40. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/shell/__init__.py +0 -0
  41. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/shell/resources/__init__.py +0 -0
  42. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/shell/updates.py +0 -0
  43. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/term/TermPageHandler.py +0 -0
  44. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/term/__init__.py +0 -0
  45. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/_internal/term/tools.py +0 -0
  46. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/__init__.py +0 -0
  47. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/api.py +0 -0
  48. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/attach.py +0 -0
  49. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/bootstrap.py +0 -0
  50. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/clear.py +0 -0
  51. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/copy.py +0 -0
  52. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/deduplicate.py +0 -0
  53. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/delete.py +0 -0
  54. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/drop.py +0 -0
  55. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/edit.py +0 -0
  56. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/install.py +0 -0
  57. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/login.py +0 -0
  58. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/os.py +0 -0
  59. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/pause.py +0 -0
  60. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/python.py +0 -0
  61. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/register.py +0 -0
  62. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/reload.py +0 -0
  63. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/restart.py +0 -0
  64. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/setup.py +0 -0
  65. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/sh.py +0 -0
  66. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/show.py +0 -0
  67. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/sql.py +0 -0
  68. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/stack.py +0 -0
  69. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/start.py +0 -0
  70. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/stop.py +0 -0
  71. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/sync.py +0 -0
  72. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/tag.py +0 -0
  73. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/uninstall.py +0 -0
  74. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/actions/verify.py +0 -0
  75. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/__init__.py +0 -0
  76. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/_chain.py +0 -0
  77. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/_events.py +0 -0
  78. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/_oauth2.py +0 -0
  79. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/_websockets.py +0 -0
  80. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/__init__.py +0 -0
  81. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/assets/__init__.py +0 -0
  82. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/assets/ansi_up.js +0 -0
  83. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/assets/banner_1920x320.png +0 -0
  84. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/assets/favicon.ico +0 -0
  85. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/assets/logo_48x48.png +0 -0
  86. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/assets/logo_500x500.png +0 -0
  87. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/__init__.py +0 -0
  88. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/custom.py +0 -0
  89. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/dashboard.py +0 -0
  90. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/jobs.py +0 -0
  91. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/login.py +0 -0
  92. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/pipes.py +0 -0
  93. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/plugins.py +0 -0
  94. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/callbacks/register.py +0 -0
  95. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/components.py +0 -0
  96. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/connectors.py +0 -0
  97. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/graphs.py +0 -0
  98. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/jobs.py +0 -0
  99. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/keys.py +0 -0
  100. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/__init__.py +0 -0
  101. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/dashboard.py +0 -0
  102. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/error.py +0 -0
  103. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/job.py +0 -0
  104. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/login.py +0 -0
  105. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/pipes.py +0 -0
  106. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/plugins.py +0 -0
  107. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pages/register.py +0 -0
  108. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/pipes.py +0 -0
  109. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/plugins.py +0 -0
  110. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/sessions.py +0 -0
  111. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/sync.py +0 -0
  112. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/users.py +0 -0
  113. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/websockets.py +0 -0
  114. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/dash/webterm.py +0 -0
  115. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/models/__init__.py +0 -0
  116. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/models/_interfaces.py +0 -0
  117. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/models/_locations.py +0 -0
  118. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/models/_metrics.py +0 -0
  119. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/models/_pipes.py +0 -0
  120. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/__init__.py +0 -0
  121. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/__init__.py +0 -0
  122. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/css/__init__.py +0 -0
  123. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/css/bootstrap.min.css +0 -0
  124. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/css/dash.css +0 -0
  125. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/css/dbc_dark.css +0 -0
  126. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/css/styles.css +0 -0
  127. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/css/xterm.css +0 -0
  128. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/ico/__init__.py +0 -0
  129. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/ico/logo.ico +0 -0
  130. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/js/__init__.py +0 -0
  131. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/js/action_button.js +0 -0
  132. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/js/main.js +0 -0
  133. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/js/terminado.js +0 -0
  134. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/js/xterm.js +0 -0
  135. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/static/png/__init__.py +0 -0
  136. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/templates/__init__.py +0 -0
  137. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/templates/index.html +0 -0
  138. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/templates/old_index.html +0 -0
  139. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/templates/secret.html +0 -0
  140. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/resources/templates/termpage.html +0 -0
  141. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/__init__.py +0 -0
  142. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_actions.py +0 -0
  143. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_connectors.py +0 -0
  144. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_index.py +0 -0
  145. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_jobs.py +0 -0
  146. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_login.py +0 -0
  147. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_misc.py +0 -0
  148. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_pipes.py +0 -0
  149. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_plugins.py +0 -0
  150. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_users.py +0 -0
  151. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_version.py +0 -0
  152. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/routes/_webterm.py +0 -0
  153. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/api/tables/__init__.py +0 -0
  154. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/__init__.py +0 -0
  155. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_dash.py +0 -0
  156. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_default.py +0 -0
  157. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_edit.py +0 -0
  158. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_environment.py +0 -0
  159. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_formatting.py +0 -0
  160. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_jobs.py +0 -0
  161. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_patch.py +0 -0
  162. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_paths.py +0 -0
  163. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_preprocess.py +0 -0
  164. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_read_config.py +0 -0
  165. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_shell.py +0 -0
  166. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/_sync.py +0 -0
  167. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/paths.py +0 -0
  168. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/resources/__init__.py +0 -0
  169. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/stack/__init__.py +0 -0
  170. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/stack/grafana/__init__.py +0 -0
  171. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/stack/mosquitto/__init__.py +0 -0
  172. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/stack/mosquitto/resources/__init__.py +0 -0
  173. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/stack/resources/__init__.py +0 -0
  174. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/config/static/__init__.py +0 -0
  175. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/_Connector.py +0 -0
  176. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/__init__.py +0 -0
  177. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_APIConnector.py +0 -0
  178. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/__init__.py +0 -0
  179. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_actions.py +0 -0
  180. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_fetch.py +0 -0
  181. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_jobs.py +0 -0
  182. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_login.py +0 -0
  183. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_misc.py +0 -0
  184. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_pipes.py +0 -0
  185. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_plugins.py +0 -0
  186. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_request.py +0 -0
  187. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_uri.py +0 -0
  188. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/api/_users.py +0 -0
  189. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/parse.py +0 -0
  190. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/plugin/PluginConnector.py +0 -0
  191. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/plugin/__init__.py +0 -0
  192. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/poll.py +0 -0
  193. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_SQLConnector.py +0 -0
  194. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/__init__.py +0 -0
  195. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_cli.py +0 -0
  196. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_plugins.py +0 -0
  197. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_uri.py +0 -0
  198. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/_users.py +0 -0
  199. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/tables/__init__.py +0 -0
  200. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/tables/types.py +0 -0
  201. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/sql/tools.py +0 -0
  202. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/valkey/_ValkeyConnector.py +0 -0
  203. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/valkey/__init__.py +0 -0
  204. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/valkey/_fetch.py +0 -0
  205. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/valkey/_pipes.py +0 -0
  206. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/valkey/_plugins.py +0 -0
  207. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/connectors/valkey/_users.py +0 -0
  208. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_bootstrap.py +0 -0
  209. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_clear.py +0 -0
  210. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_copy.py +0 -0
  211. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_data.py +0 -0
  212. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_deduplicate.py +0 -0
  213. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_delete.py +0 -0
  214. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_drop.py +0 -0
  215. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_dtypes.py +0 -0
  216. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_edit.py +0 -0
  217. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_fetch.py +0 -0
  218. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_register.py +0 -0
  219. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_show.py +0 -0
  220. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_sync.py +0 -0
  221. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Pipe/_verify.py +0 -0
  222. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/Plugin/__init__.py +0 -0
  223. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/User/_User.py +0 -0
  224. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/User/__init__.py +0 -0
  225. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/core/__init__.py +0 -0
  226. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/jobs/_Executor.py +0 -0
  227. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/jobs/_Job.py +0 -0
  228. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/jobs/__init__.py +0 -0
  229. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/jobs/systemd.py +0 -0
  230. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/plugins/_Plugin.py +0 -0
  231. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/plugins/__init__.py +0 -0
  232. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/plugins/bootstrap.py +0 -0
  233. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/__init__.py +0 -0
  234. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/_get_pipes.py +0 -0
  235. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/daemon/Daemon.py +0 -0
  236. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -0
  237. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/daemon/RotatingFile.py +0 -0
  238. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/daemon/StdinFile.py +0 -0
  239. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/daemon/__init__.py +0 -0
  240. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/daemon/_names.py +0 -0
  241. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/debug.py +0 -0
  242. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/dtypes/__init__.py +0 -0
  243. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/dtypes/sql.py +0 -0
  244. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/formatting/__init__.py +0 -0
  245. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/formatting/_jobs.py +0 -0
  246. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/formatting/_pipes.py +0 -0
  247. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/formatting/_pprint.py +0 -0
  248. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/formatting/_shell.py +0 -0
  249. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/interactive.py +0 -0
  250. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/misc.py +0 -0
  251. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/networking.py +0 -0
  252. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/packages/lazy_loader.py +0 -0
  253. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/pool.py +0 -0
  254. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/process.py +0 -0
  255. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/prompt.py +0 -0
  256. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/sql.py +0 -0
  257. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/threading.py +0 -0
  258. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/typing.py +0 -0
  259. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/venv/_Venv.py +0 -0
  260. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/venv/__init__.py +0 -0
  261. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/warnings.py +0 -0
  262. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum/utils/yaml.py +0 -0
  263. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum.egg-info/SOURCES.txt +0 -0
  264. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum.egg-info/dependency_links.txt +0 -0
  265. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum.egg-info/entry_points.txt +0 -0
  266. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum.egg-info/top_level.txt +0 -0
  267. {meerschaum-2.4.13 → meerschaum-2.5.0}/meerschaum.egg-info/zip-safe +0 -0
  268. {meerschaum-2.4.13 → meerschaum-2.5.0}/setup.cfg +0 -0
  269. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_actions.py +0 -0
  270. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_arguments.py +0 -0
  271. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_deduplicate.py +0 -0
  272. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_jobs.py +0 -0
  273. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_pipes_dtypes.py +0 -0
  274. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_sql.py +0 -0
  275. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_users.py +0 -0
  276. {meerschaum-2.4.13 → meerschaum-2.5.0}/tests/test_verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: meerschaum
3
- Version: 2.4.13
3
+ Version: 2.5.0
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Home-page: https://meerschaum.io
6
6
  Author: Bennett Meares
@@ -48,7 +48,7 @@ Requires-Dist: setuptools>=63.3.0; extra == "core"
48
48
  Requires-Dist: PyYAML>=5.3.1; extra == "core"
49
49
  Requires-Dist: pip>=22.0.4; extra == "core"
50
50
  Requires-Dist: update-checker>=0.18.0; extra == "core"
51
- Requires-Dist: semver>=3.0.0; extra == "core"
51
+ Requires-Dist: semver>=3.0.2; extra == "core"
52
52
  Requires-Dist: pathspec>=0.9.0; extra == "core"
53
53
  Requires-Dist: python-dateutil>=2.7.5; extra == "core"
54
54
  Requires-Dist: requests>=2.32.3; extra == "core"
@@ -63,8 +63,7 @@ Requires-Dist: prompt-toolkit>=3.0.39; extra == "core"
63
63
  Requires-Dist: more-itertools>=8.7.0; extra == "core"
64
64
  Requires-Dist: fasteners>=0.19.0; extra == "core"
65
65
  Requires-Dist: virtualenv>=20.1.0; extra == "core"
66
- Requires-Dist: attrs<24.2.0; extra == "core"
67
- Requires-Dist: APScheduler>=4.0.0a5; extra == "core"
66
+ Requires-Dist: attrs>=24.2.0; extra == "core"
68
67
  Requires-Dist: uv>=0.2.11; extra == "core"
69
68
  Provides-Extra: jobs
70
69
  Requires-Dist: dill>=0.3.3; extra == "jobs"
@@ -147,7 +146,7 @@ Requires-Dist: setuptools>=63.3.0; extra == "sql"
147
146
  Requires-Dist: PyYAML>=5.3.1; extra == "sql"
148
147
  Requires-Dist: pip>=22.0.4; extra == "sql"
149
148
  Requires-Dist: update-checker>=0.18.0; extra == "sql"
150
- Requires-Dist: semver>=3.0.0; extra == "sql"
149
+ Requires-Dist: semver>=3.0.2; extra == "sql"
151
150
  Requires-Dist: pathspec>=0.9.0; extra == "sql"
152
151
  Requires-Dist: python-dateutil>=2.7.5; extra == "sql"
153
152
  Requires-Dist: requests>=2.32.3; extra == "sql"
@@ -162,8 +161,7 @@ Requires-Dist: prompt-toolkit>=3.0.39; extra == "sql"
162
161
  Requires-Dist: more-itertools>=8.7.0; extra == "sql"
163
162
  Requires-Dist: fasteners>=0.19.0; extra == "sql"
164
163
  Requires-Dist: virtualenv>=20.1.0; extra == "sql"
165
- Requires-Dist: attrs<24.2.0; extra == "sql"
166
- Requires-Dist: APScheduler>=4.0.0a5; extra == "sql"
164
+ Requires-Dist: attrs>=24.2.0; extra == "sql"
167
165
  Requires-Dist: uv>=0.2.11; extra == "sql"
168
166
  Provides-Extra: dash
169
167
  Requires-Dist: Flask-Compress>=1.10.1; extra == "dash"
@@ -207,7 +205,7 @@ Requires-Dist: setuptools>=63.3.0; extra == "api"
207
205
  Requires-Dist: PyYAML>=5.3.1; extra == "api"
208
206
  Requires-Dist: pip>=22.0.4; extra == "api"
209
207
  Requires-Dist: update-checker>=0.18.0; extra == "api"
210
- Requires-Dist: semver>=3.0.0; extra == "api"
208
+ Requires-Dist: semver>=3.0.2; extra == "api"
211
209
  Requires-Dist: pathspec>=0.9.0; extra == "api"
212
210
  Requires-Dist: python-dateutil>=2.7.5; extra == "api"
213
211
  Requires-Dist: requests>=2.32.3; extra == "api"
@@ -222,8 +220,7 @@ Requires-Dist: prompt-toolkit>=3.0.39; extra == "api"
222
220
  Requires-Dist: more-itertools>=8.7.0; extra == "api"
223
221
  Requires-Dist: fasteners>=0.19.0; extra == "api"
224
222
  Requires-Dist: virtualenv>=20.1.0; extra == "api"
225
- Requires-Dist: attrs<24.2.0; extra == "api"
226
- Requires-Dist: APScheduler>=4.0.0a5; extra == "api"
223
+ Requires-Dist: attrs>=24.2.0; extra == "api"
227
224
  Requires-Dist: uv>=0.2.11; extra == "api"
228
225
  Requires-Dist: pprintpp>=0.4.0; extra == "api"
229
226
  Requires-Dist: asciitree>=0.3.3; extra == "api"
@@ -259,7 +256,7 @@ Requires-Dist: setuptools>=63.3.0; extra == "full"
259
256
  Requires-Dist: PyYAML>=5.3.1; extra == "full"
260
257
  Requires-Dist: pip>=22.0.4; extra == "full"
261
258
  Requires-Dist: update-checker>=0.18.0; extra == "full"
262
- Requires-Dist: semver>=3.0.0; extra == "full"
259
+ Requires-Dist: semver>=3.0.2; extra == "full"
263
260
  Requires-Dist: pathspec>=0.9.0; extra == "full"
264
261
  Requires-Dist: python-dateutil>=2.7.5; extra == "full"
265
262
  Requires-Dist: requests>=2.32.3; extra == "full"
@@ -274,8 +271,7 @@ Requires-Dist: prompt-toolkit>=3.0.39; extra == "full"
274
271
  Requires-Dist: more-itertools>=8.7.0; extra == "full"
275
272
  Requires-Dist: fasteners>=0.19.0; extra == "full"
276
273
  Requires-Dist: virtualenv>=20.1.0; extra == "full"
277
- Requires-Dist: attrs<24.2.0; extra == "full"
278
- Requires-Dist: APScheduler>=4.0.0a5; extra == "full"
274
+ Requires-Dist: attrs>=24.2.0; extra == "full"
279
275
  Requires-Dist: uv>=0.2.11; extra == "full"
280
276
  Requires-Dist: dill>=0.3.3; extra == "full"
281
277
  Requires-Dist: python-daemon>=0.2.3; extra == "full"
@@ -109,6 +109,7 @@ def _upgrade_meerschaum(
109
109
  class NoVenv:
110
110
  pass
111
111
 
112
+
112
113
  def _upgrade_packages(
113
114
  action: Optional[List[str]] = None,
114
115
  venv: Union[str, None, NoVenv] = NoVenv,
@@ -121,7 +122,7 @@ def _upgrade_packages(
121
122
  """
122
123
  Upgrade and install dependencies.
123
124
  If provided, upgrade only a dependency group, otherwise default to `full`.
124
-
125
+
125
126
  Examples:
126
127
  upgrade packages
127
128
  upgrade packages full
@@ -160,7 +161,7 @@ def _upgrade_packages(
160
161
  to_install = [
161
162
  install_name
162
163
  for install_name in to_install
163
- if install_name not in prereleases_to_install
164
+ if (install_name not in prereleases_to_install) or group == '_internal'
164
165
  ]
165
166
 
166
167
  success, msg = False, f"Nothing installed."
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.4.13"
5
+ __version__ = "2.5.0"
@@ -63,6 +63,8 @@ flavor_configs = {
63
63
  'fast_executemany': True,
64
64
  'isolation_level': 'AUTOCOMMIT',
65
65
  'use_setinputsizes': False,
66
+ 'pool_pre_ping': True,
67
+ 'ignore_no_transaction_on_rollback': True,
66
68
  },
67
69
  'omit_create_engine': {'method',},
68
70
  'to_sql': {
@@ -189,15 +191,18 @@ def create_engine(
189
191
  ### Install and patch required drivers.
190
192
  if self.flavor in install_flavor_drivers:
191
193
  attempt_import(*install_flavor_drivers[self.flavor], debug=debug, lazy=False, warn=False)
194
+ if self.flavor == 'mssql':
195
+ pyodbc = attempt_import('pyodbc', debug=debug, lazy=False, warn=False)
196
+ pyodbc.pooling = False
192
197
  if self.flavor in require_patching_flavors:
193
198
  from meerschaum.utils.packages import determine_version, _monkey_patch_get_distribution
194
199
  import pathlib
195
200
  for install_name, import_name in require_patching_flavors[self.flavor]:
196
201
  pkg = attempt_import(
197
202
  import_name,
198
- debug = debug,
199
- lazy = False,
200
- warn = False
203
+ debug=debug,
204
+ lazy=False,
205
+ warn=False
201
206
  )
202
207
  _monkey_patch_get_distribution(
203
208
  install_name, determine_version(pathlib.Path(pkg.__file__), venv='mrsm')
@@ -31,7 +31,7 @@ def fetch(
31
31
  ----------
32
32
  pipe: mrsm.Pipe
33
33
  The pipe object which contains the `fetch` metadata.
34
-
34
+
35
35
  - pipe.columns['datetime']: str
36
36
  - Name of the datetime column for the remote table.
37
37
  - pipe.parameters['fetch']: Dict[str, Any]
@@ -196,7 +196,7 @@ def get_pipe_metadef(
196
196
  dateadd_str(
197
197
  flavor=self.flavor,
198
198
  datepart='minute',
199
- number=((-1 * btm) if apply_backtrack else 0),
199
+ number=((-1 * btm) if apply_backtrack else 0),
200
200
  begin=begin,
201
201
  )
202
202
  if begin
@@ -88,9 +88,9 @@ def _drop_temporary_tables(self, debug: bool = False) -> SuccessTuple:
88
88
  from meerschaum.connectors.sql.tables import get_tables
89
89
  sqlalchemy = mrsm.attempt_import('sqlalchemy')
90
90
  temp_tables_table = get_tables(
91
- mrsm_instance = self,
92
- create = False,
93
- debug = debug,
91
+ mrsm_instance=self,
92
+ create=False,
93
+ debug=debug,
94
94
  )['temp_tables']
95
95
  query = (
96
96
  sqlalchemy.select(temp_tables_table.c.table)
@@ -384,7 +384,7 @@ def get_create_index_queries(
384
384
 
385
385
  Returns
386
386
  -------
387
- A dictionary of column names mapping to lists of queries.
387
+ A dictionary of index names mapping to lists of queries.
388
388
  """
389
389
  ### NOTE: Due to recent breaking changes in DuckDB, indices don't behave properly.
390
390
  if self.flavor == 'duckdb':
@@ -400,7 +400,8 @@ def get_create_index_queries(
400
400
  index_queries = {}
401
401
 
402
402
  upsert = pipe.parameters.get('upsert', False) and (self.flavor + '-upsert') in update_queries
403
- indices = pipe.get_indices()
403
+ index_names = pipe.get_indices()
404
+ indices = pipe.indices
404
405
 
405
406
  _datetime = pipe.get_columns('datetime', error=False)
406
407
  _datetime_type = pipe.dtypes.get(_datetime, 'datetime64[ns]')
@@ -409,8 +410,8 @@ def get_create_index_queries(
409
410
  if _datetime is not None else None
410
411
  )
411
412
  _datetime_index_name = (
412
- sql_item_name(indices['datetime'], self.flavor, None)
413
- if indices.get('datetime', None)
413
+ sql_item_name(index_names['datetime'], self.flavor, None)
414
+ if index_names.get('datetime', None)
414
415
  else None
415
416
  )
416
417
  _id = pipe.get_columns('id', error=False)
@@ -421,8 +422,8 @@ def get_create_index_queries(
421
422
  )
422
423
 
423
424
  _id_index_name = (
424
- sql_item_name(indices['id'], self.flavor, None)
425
- if indices.get('id', None)
425
+ sql_item_name(index_names['id'], self.flavor, None)
426
+ if index_names.get('id', None)
426
427
  else None
427
428
  )
428
429
  _pipe_name = sql_item_name(pipe.target, self.flavor, self.get_pipe_schema(pipe))
@@ -491,18 +492,22 @@ def get_create_index_queries(
491
492
  if id_query is not None:
492
493
  index_queries[_id] = id_query if isinstance(id_query, list) else [id_query]
493
494
 
494
-
495
495
  ### Create indices for other labels in `pipe.columns`.
496
- other_indices = {
496
+ other_index_names = {
497
497
  ix_key: ix_unquoted
498
- for ix_key, ix_unquoted in pipe.get_indices().items()
498
+ for ix_key, ix_unquoted in index_names.items()
499
499
  if ix_key not in ('datetime', 'id')
500
500
  }
501
- for ix_key, ix_unquoted in other_indices.items():
501
+ for ix_key, ix_unquoted in other_index_names.items():
502
502
  ix_name = sql_item_name(ix_unquoted, self.flavor, None)
503
- col = pipe.columns[ix_key]
504
- col_name = sql_item_name(col, self.flavor, None)
505
- index_queries[col] = [f"CREATE INDEX {ix_name} ON {_pipe_name} ({col_name})"]
503
+ cols = indices[ix_key]
504
+ if not isinstance(cols, (list, tuple)):
505
+ cols = [cols]
506
+ cols_names = [sql_item_name(col, self.flavor, None) for col in cols if col]
507
+ if not cols_names:
508
+ continue
509
+ cols_names_str = ", ".join(cols_names)
510
+ index_queries[ix_key] = [f"CREATE INDEX {ix_name} ON {_pipe_name} ({cols_names_str})"]
506
511
 
507
512
  existing_cols_types = pipe.get_columns_types(debug=debug)
508
513
  indices_cols_str = ', '.join(
@@ -17,8 +17,9 @@ from meerschaum.utils.warnings import warn
17
17
  ### database flavors that can use bulk insert
18
18
  _bulk_flavors = {'postgresql', 'timescaledb', 'citus'}
19
19
  ### flavors that do not support chunks
20
- _disallow_chunks_flavors = {'duckdb', 'mssql'}
20
+ _disallow_chunks_flavors = ['duckdb']
21
21
  _max_chunks_flavors = {'sqlite': 1000,}
22
+ SKIP_READ_TRANSACTION_FLAVORS: list[str] = ['mssql']
22
23
 
23
24
 
24
25
  def read(
@@ -97,7 +98,7 @@ def read(
97
98
  Defaults to `SQLConnector.schema`.
98
99
 
99
100
  as_chunks: bool, default False
100
- If `True`, return a list of DataFrames.
101
+ If `True`, return a list of DataFrames.
101
102
  Otherwise return a single DataFrame.
102
103
 
103
104
  as_iterator: bool, default False
@@ -127,7 +128,6 @@ def read(
127
128
  from meerschaum.utils.pool import get_pool
128
129
  from meerschaum.utils.dataframe import chunksize_to_npartitions, get_numeric_cols
129
130
  import warnings
130
- import inspect
131
131
  import traceback
132
132
  from decimal import Decimal
133
133
  pd = import_pandas()
@@ -140,6 +140,7 @@ def read(
140
140
  chunksize = None
141
141
  schema = schema or self.schema
142
142
 
143
+ pool = get_pool(workers=workers)
143
144
  sqlalchemy = attempt_import("sqlalchemy")
144
145
  default_chunksize = self._sys_config.get('chunksize', None)
145
146
  chunksize = chunksize if chunksize != -1 else default_chunksize
@@ -157,7 +158,7 @@ def read(
157
158
  f"The specified chunksize of {chunksize} exceeds the maximum of "
158
159
  + f"{_max_chunks_flavors[self.flavor]} for flavor '{self.flavor}'.\n"
159
160
  + f" Falling back to a chunksize of {_max_chunks_flavors[self.flavor]}.",
160
- stacklevel = 3,
161
+ stacklevel=3,
161
162
  )
162
163
  chunksize = _max_chunks_flavors[self.flavor]
163
164
 
@@ -184,8 +185,8 @@ def read(
184
185
  truncated_table_name = truncate_item_name(str(query_or_table), self.flavor)
185
186
  if truncated_table_name != str(query_or_table) and not silent:
186
187
  warn(
187
- f"Table '{name}' is too long for '{self.flavor}',"
188
- + f" will instead create the table '{truncated_name}'."
188
+ f"Table '{query_or_table}' is too long for '{self.flavor}',"
189
+ + f" will instead read the table '{truncated_table_name}'."
189
190
  )
190
191
 
191
192
  query_or_table = sql_item_name(str(query_or_table), self.flavor, schema)
@@ -204,6 +205,34 @@ def read(
204
205
 
205
206
  chunk_list = []
206
207
  chunk_hook_results = []
208
+ def _process_chunk(_chunk, _retry_on_failure: bool = True):
209
+ if not as_hook_results:
210
+ chunk_list.append(_chunk)
211
+ if chunk_hook is None:
212
+ return None
213
+
214
+ result = None
215
+ try:
216
+ result = chunk_hook(
217
+ _chunk,
218
+ workers=workers,
219
+ chunksize=chunksize,
220
+ debug=debug,
221
+ **kw
222
+ )
223
+ except Exception:
224
+ result = False, traceback.format_exc()
225
+ from meerschaum.utils.formatting import get_console
226
+ if not silent:
227
+ get_console().print_exception()
228
+
229
+ ### If the chunk fails to process, try it again one more time.
230
+ if isinstance(result, tuple) and result[0] is False:
231
+ if _retry_on_failure:
232
+ return _process_chunk(_chunk, _retry_on_failure=False)
233
+
234
+ return result
235
+
207
236
  try:
208
237
  stream_results = not as_iterator and chunk_hook is not None and chunksize is not None
209
238
  with warnings.catch_warnings():
@@ -235,52 +264,32 @@ def read(
235
264
  )
236
265
  else:
237
266
 
238
- with self.engine.begin() as transaction:
239
- with transaction.execution_options(stream_results=stream_results) as connection:
240
- chunk_generator = pd.read_sql_query(
241
- formatted_query,
242
- connection,
243
- **read_sql_query_kwargs
267
+ def get_chunk_generator(connectable):
268
+ chunk_generator = pd.read_sql_query(
269
+ formatted_query,
270
+ self.engine,
271
+ **read_sql_query_kwargs
272
+ )
273
+ to_return = (
274
+ chunk_generator
275
+ if as_iterator or chunksize is None
276
+ else (
277
+ list(pool.imap(_process_chunk, chunk_generator))
278
+ if as_hook_results
279
+ else None
244
280
  )
281
+ )
282
+ return chunk_generator, to_return
283
+
284
+ if self.flavor in SKIP_READ_TRANSACTION_FLAVORS:
285
+ chunk_generator, to_return = get_chunk_generator(self.engine)
286
+ else:
287
+ with self.engine.begin() as transaction:
288
+ with transaction.execution_options(stream_results=stream_results) as connection:
289
+ chunk_generator, to_return = get_chunk_generator(connection)
245
290
 
246
- ### `stream_results` must be False (will load everything into memory).
247
- if as_iterator or chunksize is None:
248
- return chunk_generator
249
-
250
- ### We must consume the generator in this context if using server-side cursors.
251
- if stream_results:
252
-
253
- pool = get_pool(workers=workers)
254
-
255
- def _process_chunk(_chunk, _retry_on_failure: bool = True):
256
- if not as_hook_results:
257
- chunk_list.append(_chunk)
258
- result = None
259
- if chunk_hook is not None:
260
- try:
261
- result = chunk_hook(
262
- _chunk,
263
- workers = workers,
264
- chunksize = chunksize,
265
- debug = debug,
266
- **kw
267
- )
268
- except Exception as e:
269
- result = False, traceback.format_exc()
270
- from meerschaum.utils.formatting import get_console
271
- if not silent:
272
- get_console().print_exception()
273
-
274
- ### If the chunk fails to process, try it again one more time.
275
- if isinstance(result, tuple) and result[0] is False:
276
- if _retry_on_failure:
277
- return _process_chunk(_chunk, _retry_on_failure=False)
278
-
279
- return result
280
-
281
- chunk_hook_results = list(pool.imap(_process_chunk, chunk_generator))
282
- if as_hook_results:
283
- return chunk_hook_results
291
+ if to_return is not None:
292
+ return to_return
284
293
 
285
294
  except Exception as e:
286
295
  if debug:
@@ -98,6 +98,8 @@ class Pipe:
98
98
  attributes,
99
99
  parameters,
100
100
  columns,
101
+ indices,
102
+ indexes,
101
103
  dtypes,
102
104
  get_columns,
103
105
  get_columns_types,
@@ -145,6 +147,7 @@ class Pipe:
145
147
  location: Optional[str] = None,
146
148
  parameters: Optional[Dict[str, Any]] = None,
147
149
  columns: Union[Dict[str, str], List[str], None] = None,
150
+ indices: Optional[Dict[str, Union[str, List[str]]]] = None,
148
151
  tags: Optional[List[str]] = None,
149
152
  target: Optional[str] = None,
150
153
  dtypes: Optional[Dict[str, str]] = None,
@@ -156,6 +159,7 @@ class Pipe:
156
159
  connector_keys: Optional[str] = None,
157
160
  metric_key: Optional[str] = None,
158
161
  location_key: Optional[str] = None,
162
+ indexes: Union[Dict[str, str], List[str], None] = None,
159
163
  ):
160
164
  """
161
165
  Parameters
@@ -174,10 +178,14 @@ class Pipe:
174
178
  e.g. columns and other attributes.
175
179
  You can edit these parameters with `edit pipes`.
176
180
 
177
- columns: Optional[Dict[str, str]], default None
181
+ columns: Union[Dict[str, str], List[str], None], default None
178
182
  Set the `columns` dictionary of `parameters`.
179
183
  If `parameters` is also provided, this dictionary is added under the `'columns'` key.
180
184
 
185
+ indices: Optional[Dict[str, Union[str, List[str]]]], default None
186
+ Set the `indices` dictionary of `parameters`.
187
+ If `parameters` is also provided, this dictionary is added under the `'indices'` key.
188
+
181
189
  tags: Optional[List[str]], default None
182
190
  A list of strings to be added under the `'tags'` key of `parameters`.
183
191
  You can select pipes with certain tags using `--tags`.
@@ -255,6 +263,20 @@ class Pipe:
255
263
  elif columns is not None:
256
264
  warn(f"The provided columns are of invalid type '{type(columns)}'.")
257
265
 
266
+ indices = (
267
+ indices
268
+ or indexes
269
+ or self._attributes.get('parameters', {}).get('indices', None)
270
+ or self._attributes.get('parameters', {}).get('indexes', None)
271
+ ) or columns
272
+ if isinstance(indices, dict):
273
+ indices_key = (
274
+ 'indexes'
275
+ if 'indexes' in self._attributes['parameters']
276
+ else 'indices'
277
+ )
278
+ self._attributes['parameters'][indices_key] = indices
279
+
258
280
  if isinstance(tags, (list, tuple)):
259
281
  self._attributes['parameters']['tags'] = tags
260
282
  elif tags is not None:
@@ -77,15 +77,69 @@ def columns(self) -> Union[Dict[str, str], None]:
77
77
 
78
78
 
79
79
  @columns.setter
80
- def columns(self, columns: Dict[str, str]) -> None:
80
+ def columns(self, _columns: Union[Dict[str, str], List[str]]) -> None:
81
81
  """
82
82
  Override the columns dictionary of the in-memory pipe.
83
83
  Call `meerschaum.Pipe.edit()` to persist changes.
84
84
  """
85
+ if isinstance(_columns, (list, tuple)):
86
+ _columns = {col: col for col in _columns}
85
87
  if not isinstance(columns, dict):
86
- warn(f"{self}.columns must be a dictionary, received {type(columns)}")
88
+ warn(f"{self}.columns must be a dictionary, received {type(_columns)}.")
87
89
  return
88
- self.parameters['columns'] = columns
90
+ self.parameters['columns'] = _columns
91
+
92
+
93
+ @property
94
+ def indices(self) -> Union[Dict[str, Union[str, List[str]]], None]:
95
+ """
96
+ Return the `indices` dictionary defined in `meerschaum.Pipe.parameters`.
97
+ """
98
+ indices_key = (
99
+ 'indexes'
100
+ if 'indexes' in self.parameters
101
+ else 'indices'
102
+ )
103
+ if indices_key not in self.parameters:
104
+ self.parameters[indices_key] = {}
105
+ _indices = self.parameters[indices_key]
106
+ if not isinstance(_indices, dict):
107
+ _indices = {}
108
+ self.parameters[indices_key] = _indices
109
+ return {**self.columns, **_indices}
110
+
111
+
112
+ @property
113
+ def indexes(self) -> Union[Dict[str, Union[str, List[str]]], None]:
114
+ """
115
+ Alias for `meerschaum.Pipe.indices`.
116
+ """
117
+ return self.indices
118
+
119
+
120
+ @indices.setter
121
+ def indices(self, _indices: Union[Dict[str, Union[str, List[str]]], List[str]]) -> None:
122
+ """
123
+ Override the indices dictionary of the in-memory pipe.
124
+ Call `meerschaum.Pipe.edit()` to persist changes.
125
+ """
126
+ if not isinstance(_indices, dict):
127
+ warn(f"{self}.indices must be a dictionary, received {type(_indices)}.")
128
+ return
129
+ indices_key = (
130
+ 'indexes'
131
+ if 'indexes' in self.parameters
132
+ else 'indices'
133
+ )
134
+ self.parameters[indices_key] = _indices
135
+
136
+
137
+ @indexes.setter
138
+ def indexes(self, _indexes: Union[Dict[str, Union[str, List[str]]], List[str]]) -> None:
139
+ """
140
+ Alias for `meerschaum.Pipe.indices`.
141
+ """
142
+ self.indices = _indexes
89
143
 
90
144
 
91
145
  @property
@@ -415,27 +469,55 @@ def guess_datetime(self) -> Union[str, None]:
415
469
  """
416
470
  Try to determine a pipe's datetime column.
417
471
  """
418
- dtypes = self.dtypes
472
+ _dtypes = self.dtypes
419
473
 
420
474
  ### Abort if the user explictly disallows a datetime index.
421
- if 'datetime' in dtypes:
422
- if dtypes['datetime'] is None:
475
+ if 'datetime' in _dtypes:
476
+ if _dtypes['datetime'] is None:
423
477
  return None
424
478
 
479
+ from meerschaum.utils.dtypes import are_dtypes_equal
425
480
  dt_cols = [
426
- col for col, typ in self.dtypes.items()
427
- if str(typ).startswith('datetime')
481
+ col
482
+ for col, typ in _dtypes.items()
483
+ if are_dtypes_equal(typ, 'datetime')
428
484
  ]
429
485
  if not dt_cols:
430
486
  return None
431
- return dt_cols[0]
487
+ return dt_cols[0]
432
488
 
433
489
 
434
490
  def get_indices(self) -> Dict[str, str]:
435
491
  """
436
- Return a dictionary in the form of `pipe.columns` but map to index names.
437
- """
438
- return {
439
- ix: (self.target + '_' + col + '_index')
440
- for ix, col in self.columns.items() if col
492
+ Return a dictionary mapping index keys to their names on the database.
493
+
494
+ Returns
495
+ -------
496
+ A dictionary of index keys to column names.
497
+ """
498
+ _parameters = self.parameters
499
+ _index_template = _parameters.get('index_template', "IX_{target}_{column_names}")
500
+ _indices = self.indices
501
+ _target = self.target
502
+ _column_names = {
503
+ ix: (
504
+ '_'.join(cols)
505
+ if isinstance(cols, (list, tuple))
506
+ else str(cols)
507
+ )
508
+ for ix, cols in _indices.items()
509
+ if cols
510
+ }
511
+ _index_names = {
512
+ ix: (
513
+ _index_template.format(
514
+ target=_target,
515
+ column_names=column_names,
516
+ connector_keys=self.connector_keys,
517
+ metric_key=self.connector_key,
518
+ location_key=self.location_key,
519
+ )
520
+ )
521
+ for ix, column_names in _column_names.items()
441
522
  }
523
+ return _index_names