meerschaum 2.5.1__tar.gz → 2.6.0.dev1__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.5.1/meerschaum.egg-info → meerschaum-2.6.0.dev1}/PKG-INFO +1 -1
  2. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/arguments/_parser.py +6 -1
  3. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/edit.py +6 -6
  4. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/sql.py +12 -11
  5. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_edit.py +46 -19
  6. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_read_config.py +20 -9
  7. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_version.py +1 -1
  8. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/stack/__init__.py +1 -1
  9. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_pipes.py +80 -24
  10. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_sql.py +29 -10
  11. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/valkey/_pipes.py +1 -1
  12. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/__init__.py +8 -9
  13. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_attributes.py +33 -11
  14. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_data.py +26 -7
  15. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_dtypes.py +4 -4
  16. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_fetch.py +1 -1
  17. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_sync.py +16 -4
  18. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_verify.py +1 -1
  19. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/dataframe.py +56 -29
  20. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/dtypes/__init__.py +16 -5
  21. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/dtypes/sql.py +58 -28
  22. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/misc.py +49 -16
  23. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/sql.py +224 -40
  24. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1/meerschaum.egg-info}/PKG-INFO +1 -1
  25. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_pipes_dtypes.py +57 -12
  26. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_sync.py +0 -30
  27. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/LICENSE +0 -0
  28. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/NOTICE +0 -0
  29. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/README.md +0 -0
  30. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/__init__.py +0 -0
  31. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/__main__.py +0 -0
  32. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/__init__.py +0 -0
  33. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/arguments/__init__.py +0 -0
  34. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/arguments/_parse_arguments.py +0 -0
  35. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/docs/__init__.py +0 -0
  36. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/docs/index.py +0 -0
  37. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/entry.py +0 -0
  38. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/gui/__init__.py +0 -0
  39. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/gui/app/__init__.py +0 -0
  40. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/gui/app/_windows.py +0 -0
  41. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/gui/app/actions.py +0 -0
  42. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/gui/app/pipes.py +0 -0
  43. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/shell/Shell.py +0 -0
  44. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/shell/ShellCompleter.py +0 -0
  45. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/shell/ValidAutoSuggest.py +0 -0
  46. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/shell/__init__.py +0 -0
  47. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/shell/resources/__init__.py +0 -0
  48. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/shell/updates.py +0 -0
  49. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/term/TermPageHandler.py +0 -0
  50. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/term/__init__.py +0 -0
  51. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/_internal/term/tools.py +0 -0
  52. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/__init__.py +0 -0
  53. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/api.py +0 -0
  54. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/attach.py +0 -0
  55. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/bootstrap.py +0 -0
  56. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/clear.py +0 -0
  57. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/copy.py +0 -0
  58. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/deduplicate.py +0 -0
  59. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/delete.py +0 -0
  60. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/drop.py +0 -0
  61. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/install.py +0 -0
  62. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/login.py +0 -0
  63. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/os.py +0 -0
  64. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/pause.py +0 -0
  65. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/python.py +0 -0
  66. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/register.py +0 -0
  67. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/reload.py +0 -0
  68. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/restart.py +0 -0
  69. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/setup.py +0 -0
  70. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/sh.py +0 -0
  71. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/show.py +0 -0
  72. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/stack.py +0 -0
  73. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/start.py +0 -0
  74. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/stop.py +0 -0
  75. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/sync.py +0 -0
  76. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/tag.py +0 -0
  77. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/uninstall.py +0 -0
  78. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/upgrade.py +0 -0
  79. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/actions/verify.py +0 -0
  80. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/__init__.py +0 -0
  81. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/_chain.py +0 -0
  82. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/_events.py +0 -0
  83. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/_oauth2.py +0 -0
  84. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/_websockets.py +0 -0
  85. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/__init__.py +0 -0
  86. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/assets/__init__.py +0 -0
  87. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/assets/ansi_up.js +0 -0
  88. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/assets/banner_1920x320.png +0 -0
  89. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/assets/favicon.ico +0 -0
  90. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/assets/logo_48x48.png +0 -0
  91. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/assets/logo_500x500.png +0 -0
  92. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/__init__.py +0 -0
  93. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/custom.py +0 -0
  94. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/dashboard.py +0 -0
  95. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/jobs.py +0 -0
  96. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/login.py +0 -0
  97. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/pipes.py +0 -0
  98. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/plugins.py +0 -0
  99. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/callbacks/register.py +0 -0
  100. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/components.py +0 -0
  101. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/connectors.py +0 -0
  102. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/graphs.py +0 -0
  103. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/jobs.py +0 -0
  104. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/keys.py +0 -0
  105. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/__init__.py +0 -0
  106. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/dashboard.py +0 -0
  107. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/error.py +0 -0
  108. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/job.py +0 -0
  109. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/login.py +0 -0
  110. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/pipes.py +0 -0
  111. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/plugins.py +0 -0
  112. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pages/register.py +0 -0
  113. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/pipes.py +0 -0
  114. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/plugins.py +0 -0
  115. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/sessions.py +0 -0
  116. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/sync.py +0 -0
  117. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/users.py +0 -0
  118. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/websockets.py +0 -0
  119. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/dash/webterm.py +0 -0
  120. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/models/__init__.py +0 -0
  121. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/models/_interfaces.py +0 -0
  122. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/models/_locations.py +0 -0
  123. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/models/_metrics.py +0 -0
  124. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/models/_pipes.py +0 -0
  125. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/__init__.py +0 -0
  126. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/__init__.py +0 -0
  127. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/css/__init__.py +0 -0
  128. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/css/bootstrap.min.css +0 -0
  129. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/css/dash.css +0 -0
  130. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/css/dbc_dark.css +0 -0
  131. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/css/styles.css +0 -0
  132. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/css/xterm.css +0 -0
  133. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/ico/__init__.py +0 -0
  134. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/ico/logo.ico +0 -0
  135. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/js/__init__.py +0 -0
  136. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/js/action_button.js +0 -0
  137. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/js/main.js +0 -0
  138. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/js/terminado.js +0 -0
  139. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/js/xterm.js +0 -0
  140. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/static/png/__init__.py +0 -0
  141. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/templates/__init__.py +0 -0
  142. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/templates/index.html +0 -0
  143. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/templates/old_index.html +0 -0
  144. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/templates/secret.html +0 -0
  145. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/resources/templates/termpage.html +0 -0
  146. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/__init__.py +0 -0
  147. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_actions.py +0 -0
  148. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_connectors.py +0 -0
  149. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_index.py +0 -0
  150. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_jobs.py +0 -0
  151. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_login.py +0 -0
  152. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_misc.py +0 -0
  153. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_pipes.py +0 -0
  154. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_plugins.py +0 -0
  155. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_users.py +0 -0
  156. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_version.py +0 -0
  157. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/routes/_webterm.py +0 -0
  158. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/api/tables/__init__.py +0 -0
  159. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/__init__.py +0 -0
  160. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_dash.py +0 -0
  161. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_default.py +0 -0
  162. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_environment.py +0 -0
  163. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_formatting.py +0 -0
  164. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_jobs.py +0 -0
  165. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_patch.py +0 -0
  166. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_paths.py +0 -0
  167. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_preprocess.py +0 -0
  168. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_shell.py +0 -0
  169. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/_sync.py +0 -0
  170. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/paths.py +0 -0
  171. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/resources/__init__.py +0 -0
  172. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/stack/grafana/__init__.py +0 -0
  173. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/stack/mosquitto/__init__.py +0 -0
  174. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/stack/mosquitto/resources/__init__.py +0 -0
  175. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/stack/resources/__init__.py +0 -0
  176. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/config/static/__init__.py +0 -0
  177. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/_Connector.py +0 -0
  178. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/__init__.py +0 -0
  179. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_APIConnector.py +0 -0
  180. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/__init__.py +0 -0
  181. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_actions.py +0 -0
  182. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_fetch.py +0 -0
  183. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_jobs.py +0 -0
  184. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_login.py +0 -0
  185. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_misc.py +0 -0
  186. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_pipes.py +0 -0
  187. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_plugins.py +0 -0
  188. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_request.py +0 -0
  189. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_uri.py +0 -0
  190. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/api/_users.py +0 -0
  191. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/parse.py +0 -0
  192. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/plugin/PluginConnector.py +0 -0
  193. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/plugin/__init__.py +0 -0
  194. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/poll.py +0 -0
  195. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_SQLConnector.py +0 -0
  196. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/__init__.py +0 -0
  197. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_cli.py +0 -0
  198. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_create_engine.py +0 -0
  199. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_fetch.py +0 -0
  200. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_instance.py +0 -0
  201. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_plugins.py +0 -0
  202. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_uri.py +0 -0
  203. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/_users.py +0 -0
  204. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/tables/__init__.py +0 -0
  205. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/tables/types.py +0 -0
  206. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/sql/tools.py +0 -0
  207. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/valkey/_ValkeyConnector.py +0 -0
  208. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/valkey/__init__.py +0 -0
  209. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/valkey/_fetch.py +0 -0
  210. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/valkey/_plugins.py +0 -0
  211. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/connectors/valkey/_users.py +0 -0
  212. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_bootstrap.py +0 -0
  213. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_clear.py +0 -0
  214. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_copy.py +0 -0
  215. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_deduplicate.py +0 -0
  216. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_delete.py +0 -0
  217. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_drop.py +0 -0
  218. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_edit.py +0 -0
  219. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_register.py +0 -0
  220. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Pipe/_show.py +0 -0
  221. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/Plugin/__init__.py +0 -0
  222. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/User/_User.py +0 -0
  223. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/User/__init__.py +0 -0
  224. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/core/__init__.py +0 -0
  225. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/jobs/_Executor.py +0 -0
  226. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/jobs/_Job.py +0 -0
  227. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/jobs/__init__.py +0 -0
  228. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/jobs/systemd.py +0 -0
  229. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/plugins/_Plugin.py +0 -0
  230. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/plugins/__init__.py +0 -0
  231. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/plugins/bootstrap.py +0 -0
  232. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/__init__.py +0 -0
  233. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/_get_pipes.py +0 -0
  234. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/daemon/Daemon.py +0 -0
  235. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -0
  236. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/daemon/RotatingFile.py +0 -0
  237. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/daemon/StdinFile.py +0 -0
  238. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/daemon/__init__.py +0 -0
  239. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/daemon/_names.py +0 -0
  240. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/debug.py +0 -0
  241. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/formatting/__init__.py +0 -0
  242. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/formatting/_jobs.py +0 -0
  243. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/formatting/_pipes.py +0 -0
  244. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/formatting/_pprint.py +0 -0
  245. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/formatting/_shell.py +0 -0
  246. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/interactive.py +0 -0
  247. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/networking.py +0 -0
  248. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/packages/__init__.py +0 -0
  249. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/packages/_packages.py +0 -0
  250. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/packages/lazy_loader.py +0 -0
  251. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/pool.py +0 -0
  252. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/process.py +0 -0
  253. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/prompt.py +0 -0
  254. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/schedule.py +0 -0
  255. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/threading.py +0 -0
  256. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/typing.py +0 -0
  257. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/venv/_Venv.py +0 -0
  258. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/venv/__init__.py +0 -0
  259. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/warnings.py +0 -0
  260. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum/utils/yaml.py +0 -0
  261. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum.egg-info/SOURCES.txt +0 -0
  262. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum.egg-info/dependency_links.txt +0 -0
  263. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum.egg-info/entry_points.txt +0 -0
  264. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum.egg-info/requires.txt +0 -0
  265. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum.egg-info/top_level.txt +0 -0
  266. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/meerschaum.egg-info/zip-safe +0 -0
  267. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/setup.cfg +0 -0
  268. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/setup.py +0 -0
  269. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_actions.py +0 -0
  270. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_arguments.py +0 -0
  271. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_deduplicate.py +0 -0
  272. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_jobs.py +0 -0
  273. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_pipe_data.py +0 -0
  274. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_sql.py +0 -0
  275. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_users.py +0 -0
  276. {meerschaum-2.5.1 → meerschaum-2.6.0.dev1}/tests/test_verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: meerschaum
3
- Version: 2.5.1
3
+ Version: 2.6.0.dev1
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Home-page: https://meerschaum.io
6
6
  Author: Bennett Meares
@@ -90,8 +90,13 @@ def parse_datetime(dt_str: str) -> Union[datetime, int, str]:
90
90
  except Exception as e:
91
91
  dt = None
92
92
  if dt is None:
93
- from meerschaum.utils.warnings import warn, error
93
+ from meerschaum.utils.warnings import error
94
94
  error(f"'{dt_str}' is not a valid datetime format.", stack=False)
95
+
96
+ if isinstance(dt, datetime):
97
+ from meerschaum.utils.dtypes import coerce_timezone
98
+ dt = coerce_timezone(dt)
99
+
95
100
  return dt
96
101
 
97
102
 
@@ -65,24 +65,24 @@ def _complete_edit(
65
65
  from meerschaum._internal.shell import default_action_completer
66
66
  return default_action_completer(action=(['edit'] + action), **kw)
67
67
 
68
- def _edit_config(action : Optional[List[str]] = None, **kw : Any) -> SuccessTuple:
68
+
69
+ def _edit_config(action: Optional[List[str]] = None, **kw : Any) -> SuccessTuple:
69
70
  """
70
71
  Edit Meerschaum configuration files.
71
-
72
+
72
73
  Specify a specific configuration key to edit.
73
74
  Defaults to editing `meerschaum` configuration (connectors, instance, etc.).
74
-
75
+
75
76
  Examples:
76
77
  ```
77
78
  ### Edit the main 'meerschaum' configuration.
78
79
  edit config
79
-
80
+
80
81
  ### Edit 'system' configuration.
81
82
  edit config system
82
-
83
+
83
84
  ### Create a new configuration file called 'myconfig'.
84
85
  edit config myconfig
85
-
86
86
  ```
87
87
  """
88
88
  from meerschaum.config._edit import edit_config
@@ -14,6 +14,7 @@ exec_methods = {
14
14
  'exec',
15
15
  }
16
16
 
17
+
17
18
  def sql(
18
19
  action: Optional[List[str]] = None,
19
20
  gui: bool = False,
@@ -22,40 +23,40 @@ def sql(
22
23
  **kw: Any
23
24
  ):
24
25
  """Execute a SQL query or launch an interactive CLI. All positional arguments are optional.
25
-
26
+
26
27
  Usage:
27
28
  `sql {label} {method} {query / table}`
28
-
29
+
29
30
  Options:
30
31
  - `sql {label}`
31
32
  Launch an interactive CLI. If {label} is omitted, use 'main'.
32
-
33
+
33
34
  - `sql {label} read [query / table]`
34
35
  Read a table or query as a pandas DataFrame and print the result.
35
-
36
+
36
37
  - `sql {label} exec [query]`
37
38
  Execute a query and print the success status.
38
-
39
+
39
40
  Examples:
40
41
  - `sql`
41
42
  Open an interactive CLI for `sql:main`.
42
-
43
+
43
44
  - `sql local`
44
45
  Open an interactive CLI for `sql:local`.
45
-
46
+
46
47
  - `sql table`
47
48
  Read from `table` on `sql:main`
48
49
  (translates to `SELECT * FROM table`).
49
-
50
+
50
51
  - `sql local table`
51
52
  Read from `table` on `sql:local`.
52
-
53
+
53
54
  - `sql local read table`
54
55
  Read from `table` on `sql:local`.
55
-
56
+
56
57
  - `sql "SELECT * FROM table WHERE id = 1"`
57
58
  Execute the above query on `sql:main` and print the results.
58
-
59
+
59
60
  - `sql local exec "INSERT INTO table (id) VALUES (1)"
60
61
  Execute the above query on `sql:local`.
61
62
  """
@@ -7,44 +7,71 @@ Functions for editing the configuration file
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
- import sys
11
10
  import pathlib
12
11
  from meerschaum.utils.typing import Optional, Any, SuccessTuple, Mapping, Dict, List, Union
13
12
 
13
+
14
14
  def edit_config(
15
- keys : Optional[List[str]] = None,
16
- params : Optional[Dict[str, Any]] = None,
17
- debug : bool = False,
18
- **kw : Any
19
- ) -> SuccessTuple:
15
+ keys: Optional[List[str]] = None,
16
+ params: Optional[Dict[str, Any]] = None,
17
+ debug: bool = False,
18
+ **kw: Any
19
+ ) -> SuccessTuple:
20
20
  """Edit the configuration files."""
21
21
  from meerschaum.config import get_config, config
22
- from meerschaum.config._read_config import get_keyfile_path
22
+ from meerschaum.config._read_config import get_keyfile_path, read_config
23
23
  from meerschaum.config._paths import CONFIG_DIR_PATH
24
24
  from meerschaum.utils.packages import reload_meerschaum
25
25
  from meerschaum.utils.misc import edit_file
26
- from meerschaum.utils.debug import dprint
26
+ from meerschaum.utils.warnings import warn, dprint
27
+ from meerschaum.utils.prompt import prompt
27
28
 
28
29
  if keys is None:
29
30
  keys = []
30
31
 
31
- for k in keys:
32
- ### If defined in default, create the config file.
33
- if isinstance(config, dict) and k in config:
34
- del config[k]
35
- get_config(k, write_missing=True, warn=False)
36
- edit_file(get_keyfile_path(k, create_new=True))
32
+ def _edit_key(key: str):
33
+ while True:
34
+ ### If defined in default, create the config file.
35
+ key_config = config.pop(key, None)
36
+ keyfile_path = get_keyfile_path(key, create_new=True)
37
+ get_config(key, write_missing=True, warn=False)
38
+
39
+ edit_file(get_keyfile_path(key, create_new=True))
40
+
41
+ ### TODO: verify that the file is valid. Retry if not.
42
+ try:
43
+ new_key_config = read_config(
44
+ CONFIG_DIR_PATH,
45
+ [key],
46
+ write_missing=False,
47
+ raise_parsing_errors=True,
48
+ )
49
+ except Exception:
50
+ if key_config:
51
+ config[key] = key_config
52
+ warn(f"Could not parse key '{key}'.", stack=False)
53
+ _ = prompt(f"Press [Enter] to edit '{keyfile_path}', [CTRL+C] to exit.")
54
+ continue
55
+
56
+ if new_key_config:
57
+ break
58
+
59
+ try:
60
+ for k in keys:
61
+ _edit_key(k)
62
+ except KeyboardInterrupt:
63
+ return False, f""
37
64
 
38
65
  reload_meerschaum(debug=debug)
39
66
  return (True, "Success")
40
67
 
41
68
 
42
69
  def write_config(
43
- config_dict: Optional[Dict[str, Any]] = None,
44
- directory: Union[str, pathlib.Path, None] = None,
45
- debug: bool = False,
46
- **kw : Any
47
- ) -> bool:
70
+ config_dict: Optional[Dict[str, Any]] = None,
71
+ directory: Union[str, pathlib.Path, None] = None,
72
+ debug: bool = False,
73
+ **kw: Any
74
+ ) -> bool:
48
75
  """Write YAML and JSON files to the configuration directory.
49
76
 
50
77
  Parameters
@@ -6,22 +6,26 @@ Import the config yaml file
6
6
  """
7
7
 
8
8
  from __future__ import annotations
9
+ import pathlib
10
+
9
11
  from meerschaum.utils.typing import Optional, Dict, Any, List, Tuple, Union
10
12
  from meerschaum.config import get_config
11
13
 
14
+
12
15
  def read_config(
13
- directory: Optional[str] = None,
16
+ directory: Union[pathlib.Path, str, None] = None,
14
17
  keys: Optional[List[str]] = None,
15
- write_missing : bool = True,
16
- substitute : bool = True,
17
- with_filenames : bool = False,
18
+ write_missing: bool = True,
19
+ substitute: bool = True,
20
+ with_filenames: bool = False,
21
+ raise_parsing_errors: bool = False,
18
22
  ) -> Union[Dict[str, Any], Tuple[Dict[str, Any], List[str]]]:
19
23
  """
20
24
  Read the configuration directory.
21
25
 
22
26
  Parameters
23
27
  ----------
24
- directory: Optional[str], default None
28
+ directory: Union[pathlib.Path, str, None], default None
25
29
  The directory with configuration files (.json and .yaml).
26
30
 
27
31
  keys: Optional[List[str]], default None
@@ -36,7 +40,10 @@ def read_config(
36
40
 
37
41
  with_filename: bool, default False
38
42
  If `True`, return a tuple of the configuration dictionary with a list of read filenames.
39
-
43
+
44
+ raise_parsing_errors: bool, default False
45
+ If `True`, re-raise parsing exceptions.
46
+
40
47
  Examples
41
48
  --------
42
49
  >>> read_config(keys=['meerschaum'], with_filename=True)
@@ -63,9 +70,9 @@ def read_config(
63
70
 
64
71
  default_filetype = STATIC_CONFIG['config']['default_filetype']
65
72
  filetype_loaders = {
66
- 'yml' : yaml.load,
67
- 'yaml' : yaml.load,
68
- 'json' : json.load,
73
+ 'yml': yaml.load,
74
+ 'yaml': yaml.load,
75
+ 'json': json.load,
69
76
  }
70
77
 
71
78
  ### Construct filekeys (files to parse).
@@ -167,6 +174,8 @@ def read_config(
167
174
  _config_key = filetype_loaders[_type](f)
168
175
  except Exception as e:
169
176
  print(f"Error processing file: {filepath}")
177
+ if raise_parsing_errors:
178
+ raise e
170
179
  import traceback
171
180
  traceback.print_exc()
172
181
  _config_key = {}
@@ -184,6 +193,8 @@ def read_config(
184
193
  config[symlinks_key][key] = _single_key_config[symlinks_key][key]
185
194
  break
186
195
  except Exception as e:
196
+ if raise_parsing_errors:
197
+ raise e
187
198
  print(f"Unable to parse {filename}!")
188
199
  import traceback
189
200
  traceback.print_exc()
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.5.1"
5
+ __version__ = "2.6.0.dev1"
@@ -39,7 +39,7 @@ valkey_password = 'MRSM{meerschaum:connectors:valkey:main:password}'
39
39
 
40
40
  env_dict = {
41
41
  'COMPOSE_PROJECT_NAME': 'mrsm',
42
- 'TIMESCALEDB_VERSION': 'latest-pg16-oss',
42
+ 'TIMESCALEDB_VERSION': 'latest-pg16',
43
43
  'POSTGRES_USER': db_user,
44
44
  'POSTGRES_PASSWORD': db_pass,
45
45
  'POSTGRES_DB': db_base,
@@ -404,7 +404,7 @@ def get_create_index_queries(
404
404
  indices = pipe.indices
405
405
 
406
406
  _datetime = pipe.get_columns('datetime', error=False)
407
- _datetime_type = pipe.dtypes.get(_datetime, 'datetime64[ns]')
407
+ _datetime_type = pipe.dtypes.get(_datetime, 'datetime64[ns, UTC]')
408
408
  _datetime_name = (
409
409
  sql_item_name(_datetime, self.flavor, None)
410
410
  if _datetime is not None else None
@@ -738,7 +738,7 @@ def get_pipe_data(
738
738
  dt_type = dtypes.get(_dt, 'object').lower()
739
739
  if 'datetime' not in dt_type:
740
740
  if 'int' not in dt_type:
741
- dtypes[_dt] = 'datetime64[ns]'
741
+ dtypes[_dt] = 'datetime64[ns, UTC]'
742
742
  existing_cols = pipe.get_columns_types(debug=debug)
743
743
  select_columns = (
744
744
  [
@@ -1197,7 +1197,12 @@ def sync_pipe(
1197
1197
  A `SuccessTuple` of success (`bool`) and message (`str`).
1198
1198
  """
1199
1199
  from meerschaum.utils.packages import import_pandas
1200
- from meerschaum.utils.sql import get_update_queries, sql_item_name, json_flavors, update_queries
1200
+ from meerschaum.utils.sql import (
1201
+ get_update_queries,
1202
+ sql_item_name,
1203
+ update_queries,
1204
+ get_create_table_queries,
1205
+ )
1201
1206
  from meerschaum.utils.misc import generate_password
1202
1207
  from meerschaum.utils.dataframe import get_json_cols, get_numeric_cols
1203
1208
  from meerschaum.utils.dtypes import are_dtypes_equal
@@ -1232,7 +1237,6 @@ def sync_pipe(
1232
1237
 
1233
1238
  ### if table does not exist, create it with indices
1234
1239
  is_new = False
1235
- add_cols_query = None
1236
1240
  if not pipe.exists(debug=debug):
1237
1241
  check_existing = False
1238
1242
  is_new = True
@@ -1252,9 +1256,7 @@ def sync_pipe(
1252
1256
 
1253
1257
  ### NOTE: Oracle SQL < 23c (2023) and SQLite does not support booleans,
1254
1258
  ### so infer bools and persist them to `dtypes`.
1255
- ### MSSQL supports `BIT` for booleans, but we coerce bools to int for MSSQL
1256
- ### to avoid merge issues.
1257
- if self.flavor in ('oracle', 'sqlite', 'mssql', 'mysql', 'mariadb'):
1259
+ if self.flavor in ('oracle', 'sqlite', 'mysql', 'mariadb'):
1258
1260
  pipe_dtypes = pipe.dtypes
1259
1261
  new_bool_cols = {
1260
1262
  col: 'bool[pyarrow]'
@@ -1309,7 +1311,60 @@ def sync_pipe(
1309
1311
  'schema': self.get_pipe_schema(pipe),
1310
1312
  })
1311
1313
 
1314
+ primary_key = pipe.columns.get('primary', None)
1315
+ new_dtypes = {
1316
+ **{
1317
+ col: str(typ)
1318
+ for col, typ in unseen_df.dtypes.items()
1319
+ },
1320
+ **{
1321
+ col: 'int'
1322
+ for col_ix, col in pipe.columns.items()
1323
+ if col_ix != 'primary'
1324
+ },
1325
+ **pipe.dtypes
1326
+ } if is_new else {}
1327
+ autoincrement = (
1328
+ pipe.parameters.get('autoincrement', False)
1329
+ or (is_new and primary_key and primary_key not in new_dtypes)
1330
+ )
1331
+ if autoincrement and autoincrement not in pipe.parameters:
1332
+ pipe.parameters['autoincrement'] = autoincrement
1333
+ edit_success, edit_msg = pipe.edit(debug=debug)
1334
+ if not edit_success:
1335
+ return edit_success, edit_msg
1336
+
1337
+ if autoincrement and primary_key and primary_key not in df.columns:
1338
+ if unseen_df is not None and primary_key in unseen_df.columns:
1339
+ del unseen_df[primary_key]
1340
+ if update_df is not None and primary_key in update_df.columns:
1341
+ del update_df[primary_key]
1342
+ if delta_df is not None and primary_key in delta_df.columns:
1343
+ del delta_df[primary_key]
1344
+
1345
+ if is_new:
1346
+ if autoincrement:
1347
+ _ = new_dtypes.pop(primary_key, None)
1348
+
1349
+ ### TODO: see if this can be removed
1350
+ if 'datetime' in pipe.columns and self.flavor == 'timescaledb':
1351
+ primary_key = None
1352
+
1353
+ create_table_queries = get_create_table_queries(
1354
+ new_dtypes,
1355
+ pipe.target,
1356
+ self.flavor,
1357
+ schema=self.get_pipe_schema(pipe),
1358
+ primary_key=primary_key,
1359
+ )
1360
+ create_success = all(
1361
+ self.exec_queries(create_table_queries, break_on_error=True, rollback=True, debug=debug)
1362
+ )
1363
+ if not create_success:
1364
+ warn(f"Failed to create '{pipe.target}'. Continuing...")
1365
+
1312
1366
  stats = self.to_sql(unseen_df, **unseen_kw)
1367
+
1313
1368
  if is_new:
1314
1369
  if not self.create_indices(pipe, debug=debug):
1315
1370
  warn(f"Failed to create indices for {pipe}. Continuing...")
@@ -1358,7 +1413,7 @@ def sync_pipe(
1358
1413
  ]
1359
1414
  update_queries = get_update_queries(
1360
1415
  pipe.target,
1361
- temp_target,
1416
+ temp_target,
1362
1417
  self,
1363
1418
  join_cols,
1364
1419
  upsert=upsert,
@@ -1960,7 +2015,7 @@ def get_sync_time(
1960
2015
  table = sql_item_name(pipe.target, self.flavor, self.get_pipe_schema(pipe))
1961
2016
 
1962
2017
  dt_col = pipe.columns.get('datetime', None)
1963
- dt_type = pipe.dtypes.get(dt_col, 'datetime64[ns]')
2018
+ dt_type = pipe.dtypes.get(dt_col, 'datetime64[ns, UTC]')
1964
2019
  if not dt_col:
1965
2020
  _dt = pipe.guess_datetime()
1966
2021
  dt = sql_item_name(_dt, self.flavor, None) if _dt else None
@@ -2366,7 +2421,7 @@ def get_pipe_columns_types(
2366
2421
  ----------
2367
2422
  pipe: mrsm.Pipe:
2368
2423
  The pipe to get the columns for.
2369
-
2424
+
2370
2425
  Returns
2371
2426
  -------
2372
2427
  A dictionary of columns names (`str`) and types (`str`).
@@ -2381,17 +2436,18 @@ def get_pipe_columns_types(
2381
2436
  }
2382
2437
  >>>
2383
2438
  """
2439
+ from meerschaum.utils.sql import get_table_cols_types
2384
2440
  if not pipe.exists(debug=debug):
2385
2441
  return {}
2386
2442
 
2387
- if self.flavor == 'duckdb':
2388
- from meerschaum.utils.sql import get_table_cols_types
2389
- return get_table_cols_types(
2390
- pipe.target,
2391
- self,
2392
- flavor=self.flavor,
2393
- schema=self.get_pipe_schema(pipe),
2394
- )
2443
+ # if self.flavor not in ('oracle', 'mysql', 'mariadb'):
2444
+ return get_table_cols_types(
2445
+ pipe.target,
2446
+ self,
2447
+ flavor=self.flavor,
2448
+ schema=self.get_pipe_schema(pipe),
2449
+ debug=debug,
2450
+ )
2395
2451
 
2396
2452
  table_columns = {}
2397
2453
  try:
@@ -2823,11 +2879,11 @@ def get_alter_columns_queries(
2823
2879
 
2824
2880
 
2825
2881
  def get_to_sql_dtype(
2826
- self,
2827
- pipe: 'mrsm.Pipe',
2828
- df: 'pd.DataFrame',
2829
- update_dtypes: bool = True,
2830
- ) -> Dict[str, 'sqlalchemy.sql.visitors.TraversibleType']:
2882
+ self,
2883
+ pipe: 'mrsm.Pipe',
2884
+ df: 'pd.DataFrame',
2885
+ update_dtypes: bool = True,
2886
+ ) -> Dict[str, 'sqlalchemy.sql.visitors.TraversibleType']:
2831
2887
  """
2832
2888
  Given a pipe and DataFrame, return the `dtype` dictionary for `to_sql()`.
2833
2889
 
@@ -2947,7 +3003,7 @@ def deduplicate_pipe(
2947
3003
  duplicates_cte_name = sql_item_name('dups', self.flavor, None)
2948
3004
  duplicate_row_number_name = sql_item_name('dup_row_num', self.flavor, None)
2949
3005
  previous_row_number_name = sql_item_name('prev_row_num', self.flavor, None)
2950
-
3006
+
2951
3007
  index_list_str = (
2952
3008
  sql_item_name(dt_col, self.flavor, None)
2953
3009
  if dt_col
@@ -17,8 +17,8 @@ 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']
21
- _max_chunks_flavors = {'sqlite': 1000,}
20
+ _disallow_chunks_flavors = []
21
+ _max_chunks_flavors = {'sqlite': 1000}
22
22
  SKIP_READ_TRANSACTION_FLAVORS: list[str] = ['mssql']
23
23
 
24
24
 
@@ -123,7 +123,8 @@ def read(
123
123
  if chunks is not None and chunks <= 0:
124
124
  return []
125
125
  from meerschaum.utils.sql import sql_item_name, truncate_item_name
126
- from meerschaum.utils.dtypes.sql import NUMERIC_PRECISION_FLAVORS
126
+ from meerschaum.utils.dtypes import are_dtypes_equal, coerce_timezone
127
+ from meerschaum.utils.dtypes.sql import NUMERIC_PRECISION_FLAVORS, TIMEZONE_NAIVE_FLAVORS
127
128
  from meerschaum.utils.packages import attempt_import, import_pandas
128
129
  from meerschaum.utils.pool import get_pool
129
130
  from meerschaum.utils.dataframe import chunksize_to_npartitions, get_numeric_cols
@@ -139,6 +140,16 @@ def read(
139
140
  if is_dask:
140
141
  chunksize = None
141
142
  schema = schema or self.schema
143
+ utc_dt_cols = [
144
+ col
145
+ for col, typ in dtype.items()
146
+ if are_dtypes_equal(typ, 'datetime') and 'utc' in typ.lower()
147
+ ] if dtype else []
148
+
149
+ if dtype and utc_dt_cols and self.flavor in TIMEZONE_NAIVE_FLAVORS:
150
+ dtype = dtype.copy()
151
+ for col in utc_dt_cols:
152
+ dtype[col] = 'datetime64[ns]'
142
153
 
143
154
  pool = get_pool(workers=workers)
144
155
  sqlalchemy = attempt_import("sqlalchemy")
@@ -162,7 +173,6 @@ def read(
162
173
  )
163
174
  chunksize = _max_chunks_flavors[self.flavor]
164
175
 
165
- ### NOTE: A bug in duckdb_engine does not allow for chunks.
166
176
  if chunksize is not None and self.flavor in _disallow_chunks_flavors:
167
177
  chunksize = None
168
178
 
@@ -206,6 +216,9 @@ def read(
206
216
  chunk_list = []
207
217
  chunk_hook_results = []
208
218
  def _process_chunk(_chunk, _retry_on_failure: bool = True):
219
+ if self.flavor in TIMEZONE_NAIVE_FLAVORS:
220
+ for col in utc_dt_cols:
221
+ _chunk[col] = coerce_timezone(_chunk[col], strip_timezone=False)
209
222
  if not as_hook_results:
210
223
  chunk_list.append(_chunk)
211
224
  if chunk_hook is None:
@@ -765,7 +778,7 @@ def to_sql(
765
778
  DROP_IF_EXISTS_FLAVORS,
766
779
  )
767
780
  from meerschaum.utils.dataframe import get_json_cols, get_numeric_cols, get_uuid_cols
768
- from meerschaum.utils.dtypes import are_dtypes_equal, quantize_decimal
781
+ from meerschaum.utils.dtypes import are_dtypes_equal, quantize_decimal, coerce_timezone
769
782
  from meerschaum.utils.dtypes.sql import (
770
783
  NUMERIC_PRECISION_FLAVORS,
771
784
  PD_TO_SQLALCHEMY_DTYPES_FLAVORS,
@@ -848,7 +861,6 @@ def to_sql(
848
861
  if not success:
849
862
  warn(f"Unable to drop {name}")
850
863
 
851
-
852
864
  ### Enforce NVARCHAR(2000) as text instead of CLOB.
853
865
  dtype = to_sql_kw.get('dtype', {})
854
866
  for col, typ in df.dtypes.items():
@@ -858,11 +870,18 @@ def to_sql(
858
870
  dtype[col] = sqlalchemy.types.INTEGER
859
871
  to_sql_kw['dtype'] = dtype
860
872
  elif self.flavor == 'mssql':
873
+ pass
874
+ ### TODO clean this up
875
+ # dtype = to_sql_kw.get('dtype', {})
876
+ # for col, typ in df.dtypes.items():
877
+ # if are_dtypes_equal(str(typ), 'bool'):
878
+ # dtype[col] = sqlalchemy.types.INTEGER
879
+ # to_sql_kw['dtype'] = dtype
880
+ elif self.flavor == 'duckdb':
861
881
  dtype = to_sql_kw.get('dtype', {})
862
- for col, typ in df.dtypes.items():
863
- if are_dtypes_equal(str(typ), 'bool'):
864
- dtype[col] = sqlalchemy.types.INTEGER
865
- to_sql_kw['dtype'] = dtype
882
+ dt_cols = [col for col, typ in df.dtypes.items() if are_dtypes_equal(str(typ), 'datetime')]
883
+ for col in dt_cols:
884
+ df[col] = coerce_timezone(df[col], strip_utc=False)
866
885
 
867
886
  ### Check for JSON columns.
868
887
  if self.flavor not in json_flavors:
@@ -706,7 +706,7 @@ def get_sync_time(
706
706
  """
707
707
  from meerschaum.utils.dtypes import are_dtypes_equal
708
708
  dt_col = pipe.columns.get('datetime', None)
709
- dt_typ = pipe.dtypes.get(dt_col, 'datetime64[ns]')
709
+ dt_typ = pipe.dtypes.get(dt_col, 'datetime64[ns, UTC]')
710
710
  if not dt_col:
711
711
  return None
712
712