meerschaum 3.0.8__tar.gz → 3.0.9__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 (296) hide show
  1. {meerschaum-3.0.8/meerschaum.egg-info → meerschaum-3.0.9}/PKG-INFO +1 -1
  2. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/bootstrap.py +10 -1
  3. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_default.py +1 -1
  4. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_version.py +1 -1
  5. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_SQLConnector.py +1 -1
  6. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_pipes.py +239 -2
  7. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_sql.py +6 -31
  8. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/dtypes/__init__.py +90 -12
  9. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/dtypes/sql.py +3 -3
  10. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/sql.py +19 -1
  11. {meerschaum-3.0.8 → meerschaum-3.0.9/meerschaum.egg-info}/PKG-INFO +1 -1
  12. {meerschaum-3.0.8 → meerschaum-3.0.9}/LICENSE +0 -0
  13. {meerschaum-3.0.8 → meerschaum-3.0.9}/MANIFEST.in +0 -0
  14. {meerschaum-3.0.8 → meerschaum-3.0.9}/NOTICE +0 -0
  15. {meerschaum-3.0.8 → meerschaum-3.0.9}/README.md +0 -0
  16. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/__init__.py +0 -0
  17. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/__main__.py +0 -0
  18. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/__init__.py +0 -0
  19. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/arguments/__init__.py +0 -0
  20. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/arguments/_parse_arguments.py +0 -0
  21. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/arguments/_parser.py +0 -0
  22. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/cli/__init__.py +0 -0
  23. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/cli/daemons.py +0 -0
  24. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/cli/entry.py +0 -0
  25. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/cli/workers.py +0 -0
  26. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/docs/__init__.py +0 -0
  27. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/docs/index.py +0 -0
  28. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/entry.py +0 -0
  29. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/shell/Shell.py +0 -0
  30. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/shell/ShellCompleter.py +0 -0
  31. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/shell/ValidAutoSuggest.py +0 -0
  32. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/shell/__init__.py +0 -0
  33. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/shell/resources/__init__.py +0 -0
  34. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/shell/updates.py +0 -0
  35. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/static.py +0 -0
  36. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/term/TermPageHandler.py +0 -0
  37. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/term/__init__.py +0 -0
  38. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/_internal/term/tools.py +0 -0
  39. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/__init__.py +0 -0
  40. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/api.py +0 -0
  41. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/attach.py +0 -0
  42. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/clear.py +0 -0
  43. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/copy.py +0 -0
  44. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/deduplicate.py +0 -0
  45. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/delete.py +0 -0
  46. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/drop.py +0 -0
  47. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/edit.py +0 -0
  48. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/index.py +0 -0
  49. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/install.py +0 -0
  50. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/login.py +0 -0
  51. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/os.py +0 -0
  52. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/pause.py +0 -0
  53. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/python.py +0 -0
  54. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/register.py +0 -0
  55. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/reload.py +0 -0
  56. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/restart.py +0 -0
  57. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/setup.py +0 -0
  58. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/sh.py +0 -0
  59. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/show.py +0 -0
  60. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/sql.py +0 -0
  61. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/stack.py +0 -0
  62. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/start.py +0 -0
  63. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/stop.py +0 -0
  64. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/sync.py +0 -0
  65. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/tag.py +0 -0
  66. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/uninstall.py +0 -0
  67. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/upgrade.py +0 -0
  68. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/actions/verify.py +0 -0
  69. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/__init__.py +0 -0
  70. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/_chain.py +0 -0
  71. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/_chunks.py +0 -0
  72. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/_events.py +0 -0
  73. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/_exceptions.py +0 -0
  74. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/_oauth2.py +0 -0
  75. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/_tokens.py +0 -0
  76. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/_websockets.py +0 -0
  77. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/__init__.py +0 -0
  78. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/assets/__init__.py +0 -0
  79. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/assets/ansi_up.js +0 -0
  80. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/assets/banner_1920x320.png +0 -0
  81. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/assets/favicon.ico +0 -0
  82. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/assets/logo_48x48.png +0 -0
  83. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/assets/logo_500x500.png +0 -0
  84. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/__init__.py +0 -0
  85. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/custom.py +0 -0
  86. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/dashboard.py +0 -0
  87. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/jobs.py +0 -0
  88. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/login.py +0 -0
  89. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/pipes.py +0 -0
  90. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/plugins.py +0 -0
  91. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/register.py +0 -0
  92. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/settings/__init__.py +0 -0
  93. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/settings/password_reset.py +0 -0
  94. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/callbacks/tokens.py +0 -0
  95. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/components.py +0 -0
  96. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/connectors.py +0 -0
  97. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/graphs.py +0 -0
  98. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/jobs.py +0 -0
  99. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/keys.py +0 -0
  100. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/__init__.py +0 -0
  101. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/dashboard.py +0 -0
  102. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/error.py +0 -0
  103. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/jobs.py +0 -0
  104. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/login.py +0 -0
  105. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/pipes.py +0 -0
  106. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/plugins.py +0 -0
  107. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/register.py +0 -0
  108. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/settings/__init__.py +0 -0
  109. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/settings/password_reset.py +0 -0
  110. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pages/tokens.py +0 -0
  111. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/pipes.py +0 -0
  112. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/plugins.py +0 -0
  113. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/sessions.py +0 -0
  114. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/sync.py +0 -0
  115. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/tokens.py +0 -0
  116. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/users.py +0 -0
  117. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/websockets.py +0 -0
  118. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/dash/webterm.py +0 -0
  119. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/models/__init__.py +0 -0
  120. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/models/_actions.py +0 -0
  121. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/models/_pipes.py +0 -0
  122. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/models/_tokens.py +0 -0
  123. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/__init__.py +0 -0
  124. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/__init__.py +0 -0
  125. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/css/__init__.py +0 -0
  126. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/css/bootstrap.min.css +0 -0
  127. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/css/dash.css +0 -0
  128. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/css/dbc_dark.css +0 -0
  129. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/css/styles.css +0 -0
  130. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/css/xterm.css +0 -0
  131. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/ico/__init__.py +0 -0
  132. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/ico/logo.ico +0 -0
  133. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/js/__init__.py +0 -0
  134. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/js/action_button.js +0 -0
  135. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/js/main.js +0 -0
  136. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/js/terminado.js +0 -0
  137. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/js/xterm-addon-unicode11.js +0 -0
  138. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/js/xterm.js +0 -0
  139. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/static/png/__init__.py +0 -0
  140. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/templates/__init__.py +0 -0
  141. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/templates/index.html +0 -0
  142. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/templates/old_index.html +0 -0
  143. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/templates/secret.html +0 -0
  144. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/resources/templates/termpage.html +0 -0
  145. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/__init__.py +0 -0
  146. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_actions.py +0 -0
  147. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_connectors.py +0 -0
  148. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_index.py +0 -0
  149. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_jobs.py +0 -0
  150. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_login.py +0 -0
  151. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_misc.py +0 -0
  152. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_pipes.py +0 -0
  153. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_plugins.py +0 -0
  154. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_tokens.py +0 -0
  155. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_users.py +0 -0
  156. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_version.py +0 -0
  157. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/routes/_webterm.py +0 -0
  158. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/api/tables/__init__.py +0 -0
  159. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/__init__.py +0 -0
  160. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_dash.py +0 -0
  161. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_edit.py +0 -0
  162. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_formatting.py +0 -0
  163. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_jobs.py +0 -0
  164. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_patch.py +0 -0
  165. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_paths.py +0 -0
  166. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_preprocess.py +0 -0
  167. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_read_config.py +0 -0
  168. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_shell.py +0 -0
  169. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/_sync.py +0 -0
  170. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/environment.py +0 -0
  171. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/paths.py +0 -0
  172. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/resources/__init__.py +0 -0
  173. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/stack/__init__.py +0 -0
  174. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/stack/grafana/__init__.py +0 -0
  175. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/stack/mosquitto/__init__.py +0 -0
  176. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/stack/mosquitto/resources/__init__.py +0 -0
  177. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/stack/resources/__init__.py +0 -0
  178. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/config/static.py +0 -0
  179. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/_Connector.py +0 -0
  180. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/__init__.py +0 -0
  181. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_APIConnector.py +0 -0
  182. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/__init__.py +0 -0
  183. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_actions.py +0 -0
  184. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_fetch.py +0 -0
  185. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_jobs.py +0 -0
  186. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_login.py +0 -0
  187. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_misc.py +0 -0
  188. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_pipes.py +0 -0
  189. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_plugins.py +0 -0
  190. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_request.py +0 -0
  191. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_tokens.py +0 -0
  192. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_uri.py +0 -0
  193. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/api/_users.py +0 -0
  194. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/instance/_InstanceConnector.py +0 -0
  195. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/instance/__init__.py +0 -0
  196. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/instance/_pipes.py +0 -0
  197. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/instance/_plugins.py +0 -0
  198. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/instance/_tokens.py +0 -0
  199. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/instance/_users.py +0 -0
  200. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/parse.py +0 -0
  201. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/plugin/PluginConnector.py +0 -0
  202. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/plugin/__init__.py +0 -0
  203. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/poll.py +0 -0
  204. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/__init__.py +0 -0
  205. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_cli.py +0 -0
  206. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_create_engine.py +0 -0
  207. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_fetch.py +0 -0
  208. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_instance.py +0 -0
  209. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_plugins.py +0 -0
  210. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_uri.py +0 -0
  211. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/_users.py +0 -0
  212. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/tables/__init__.py +0 -0
  213. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/tables/types.py +0 -0
  214. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/sql/tools.py +0 -0
  215. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/valkey/_ValkeyConnector.py +0 -0
  216. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/valkey/__init__.py +0 -0
  217. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/valkey/_fetch.py +0 -0
  218. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/valkey/_pipes.py +0 -0
  219. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/valkey/_plugins.py +0 -0
  220. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/connectors/valkey/_users.py +0 -0
  221. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/__init__.py +0 -0
  222. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_attributes.py +0 -0
  223. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_bootstrap.py +0 -0
  224. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_cache.py +0 -0
  225. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_clear.py +0 -0
  226. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_copy.py +0 -0
  227. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_data.py +0 -0
  228. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_deduplicate.py +0 -0
  229. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_delete.py +0 -0
  230. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_drop.py +0 -0
  231. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_dtypes.py +0 -0
  232. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_edit.py +0 -0
  233. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_fetch.py +0 -0
  234. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_index.py +0 -0
  235. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_register.py +0 -0
  236. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_show.py +0 -0
  237. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_sync.py +0 -0
  238. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Pipe/_verify.py +0 -0
  239. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Plugin/_Plugin.py +0 -0
  240. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Plugin/__init__.py +0 -0
  241. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Token/_Token.py +0 -0
  242. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/Token/__init__.py +0 -0
  243. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/User/_User.py +0 -0
  244. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/User/__init__.py +0 -0
  245. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/core/__init__.py +0 -0
  246. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/jobs/_Executor.py +0 -0
  247. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/jobs/_Job.py +0 -0
  248. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/jobs/__init__.py +0 -0
  249. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/jobs/systemd.py +0 -0
  250. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/models/__init__.py +0 -0
  251. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/models/pipes.py +0 -0
  252. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/models/tokens.py +0 -0
  253. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/models/users.py +0 -0
  254. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/plugins/__init__.py +0 -0
  255. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/plugins/bootstrap.py +0 -0
  256. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/__init__.py +0 -0
  257. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/_get_pipes.py +0 -0
  258. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/daemon/Daemon.py +0 -0
  259. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -0
  260. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/daemon/RotatingFile.py +0 -0
  261. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/daemon/StdinFile.py +0 -0
  262. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/daemon/__init__.py +0 -0
  263. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/daemon/_names.py +0 -0
  264. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/dataframe.py +0 -0
  265. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/debug.py +0 -0
  266. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/formatting/__init__.py +0 -0
  267. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/formatting/_jobs.py +0 -0
  268. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/formatting/_pipes.py +0 -0
  269. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/formatting/_pprint.py +0 -0
  270. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/formatting/_shell.py +0 -0
  271. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/interactive.py +0 -0
  272. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/misc.py +0 -0
  273. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/networking.py +0 -0
  274. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/packages/__init__.py +0 -0
  275. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/packages/_packages.py +0 -0
  276. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/packages/lazy_loader.py +0 -0
  277. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/pipes.py +0 -0
  278. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/pool.py +0 -0
  279. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/process.py +0 -0
  280. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/prompt.py +0 -0
  281. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/schedule.py +0 -0
  282. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/threading.py +0 -0
  283. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/typing.py +0 -0
  284. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/venv/_Venv.py +0 -0
  285. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/venv/__init__.py +0 -0
  286. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/warnings.py +0 -0
  287. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum/utils/yaml.py +0 -0
  288. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum.egg-info/SOURCES.txt +0 -0
  289. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum.egg-info/dependency_links.txt +0 -0
  290. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum.egg-info/entry_points.txt +0 -0
  291. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum.egg-info/requires.txt +0 -0
  292. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum.egg-info/top_level.txt +0 -0
  293. {meerschaum-3.0.8 → meerschaum-3.0.9}/meerschaum.egg-info/zip-safe +0 -0
  294. {meerschaum-3.0.8 → meerschaum-3.0.9}/pyproject.toml +0 -0
  295. {meerschaum-3.0.8 → meerschaum-3.0.9}/setup.cfg +0 -0
  296. {meerschaum-3.0.8 → meerschaum-3.0.9}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meerschaum
3
- Version: 3.0.8
3
+ Version: 3.0.9
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Author-email: Bennett Meares <bennett.meares@gmail.com>
6
6
  Maintainer-email: Bennett Meares <bennett.meares@gmail.com>
@@ -422,8 +422,17 @@ def _bootstrap_plugins(
422
422
  """
423
423
  Launch an interactive wizard to guide the user to creating a new plugin.
424
424
  """
425
- from meerschaum.utils.prompt import prompt
425
+ from meerschaum.utils.prompt import prompt, yes_no
426
426
  from meerschaum.plugins.bootstrap import bootstrap_plugin
427
+ from meerschaum.config.paths import PLUGINS_DIR_PATHS
428
+
429
+ for dir_path in PLUGINS_DIR_PATHS:
430
+ if not dir_path.exists():
431
+ create_dir_path = yes_no(f"Create path '{dir_path}'?", default='y')
432
+ if create_dir_path:
433
+ dir_path.mkdir(parents=True, exist_ok=True)
434
+ else:
435
+ return False, "Create missing plugins paths before bootstrapping."
427
436
 
428
437
  if not action:
429
438
  action = [prompt("Enter the name of your new plugin:")]
@@ -163,7 +163,7 @@ default_system_config = {
163
163
  'uv_pip': True,
164
164
  'systemd_healthcheck': False,
165
165
  'valkey_session_cache': True,
166
- 'cli_daemon': True,
166
+ 'cli_daemon': False,
167
167
  },
168
168
  }
169
169
 
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "3.0.8"
5
+ __version__ = "3.0.9"
@@ -36,7 +36,6 @@ class SQLConnector(InstanceConnector):
36
36
  exec_queries,
37
37
  get_connection,
38
38
  _cleanup_connections,
39
- _init_geopackage_table,
40
39
  )
41
40
  from meerschaum.utils.sql import test_connection
42
41
  from ._fetch import fetch, get_pipe_metadef
@@ -74,6 +73,7 @@ class SQLConnector(InstanceConnector):
74
73
  create_pipe_indices,
75
74
  drop_pipe_indices,
76
75
  get_pipe_index_names,
76
+ _init_geopackage_pipe,
77
77
  )
78
78
  from ._plugins import (
79
79
  get_plugins_pipe,
@@ -1564,7 +1564,7 @@ def create_pipe_table_from_df(
1564
1564
  )
1565
1565
  from meerschaum.utils.dtypes.sql import get_db_type_from_pd_type
1566
1566
  if self.flavor == 'geopackage':
1567
- init_success, init_msg = self._init_geopackage_table(df, pipe.target, debug=debug)
1567
+ init_success, init_msg = self._init_geopackage_pipe(df, pipe, debug=debug)
1568
1568
  if not init_success:
1569
1569
  return init_success, init_msg
1570
1570
 
@@ -1625,7 +1625,7 @@ def create_pipe_table_from_df(
1625
1625
  else f"Failed to create {target_name}."
1626
1626
  )
1627
1627
  if success and self.flavor == 'geopackage':
1628
- return self._init_geopackage_table(df, target, debug=debug)
1628
+ return self._init_geopackage_pipe(df, pipe, debug=debug)
1629
1629
 
1630
1630
  return success, msg
1631
1631
 
@@ -3092,6 +3092,7 @@ def get_pipe_columns_types(
3092
3092
  return {}
3093
3093
 
3094
3094
  if self.flavor not in ('oracle', 'mysql', 'mariadb', 'sqlite', 'geopackage'):
3095
+ # if self.flavor not in ('oracle', 'mysql', 'mariadb'):
3095
3096
  return get_table_cols_types(
3096
3097
  pipe.target,
3097
3098
  self,
@@ -3358,6 +3359,11 @@ def get_alter_columns_queries(
3358
3359
  'date': 'datetime',
3359
3360
  'numeric': 'int',
3360
3361
  })
3362
+ elif self.flavor == 'geopackage':
3363
+ pd_db_df_aliases.update({
3364
+ 'geometry': 'bytes',
3365
+ 'bytes': 'geometry',
3366
+ })
3361
3367
 
3362
3368
  altered_cols = {
3363
3369
  col: (db_cols_types.get(col, 'object'), typ)
@@ -3939,3 +3945,234 @@ def _enforce_pipe_dtypes_chunks_hook(
3939
3945
  Enforce a pipe's dtypes on each chunk.
3940
3946
  """
3941
3947
  return pipe.enforce_dtypes(chunk_df, debug=debug)
3948
+
3949
+
3950
+ def _init_geopackage_pipe(
3951
+ self,
3952
+ df: 'pd.DataFrame',
3953
+ pipe: mrsm.Pipe,
3954
+ debug: bool = False,
3955
+ ) -> SuccessTuple:
3956
+ """
3957
+ Initialize the geopackage schema tables from a DataFrame.
3958
+ """
3959
+ import pathlib
3960
+ import shutil
3961
+ from meerschaum.utils.sql import (
3962
+ get_table_cols_types,
3963
+ get_table_cols_indices,
3964
+ get_create_table_queries,
3965
+ table_exists,
3966
+ )
3967
+ from meerschaum.utils.dtypes import get_geometry_type_srid
3968
+ from meerschaum.utils.dtypes.sql import get_pd_type_from_db_type
3969
+ from meerschaum.utils.misc import generate_password
3970
+ from meerschaum.config.paths import SQL_CONN_CACHE_RESOURCES_PATH
3971
+ from meerschaum.connectors import connectors
3972
+ database = self.__dict__.get('database', self.parse_uri(self.URI).get('database', None))
3973
+ if not database:
3974
+ return False, f"Could not determine database for '{self}'."
3975
+
3976
+ table = pipe.target
3977
+
3978
+ tmp_id = generate_password(8)
3979
+ self_sqlite = mrsm.get_connector(
3980
+ f"sql:{self.label}_{tmp_id}",
3981
+ flavor='sqlite',
3982
+ database=database,
3983
+ )
3984
+ database_path = pathlib.Path(database)
3985
+ create_new = False
3986
+ failed = False
3987
+ mode = 'w' if not database_path.exists() else 'a'
3988
+ table_is_fresh = not table_exists(table, self_sqlite, debug=debug)
3989
+ geom_cols_types = {
3990
+ col: get_geometry_type_srid(typ)
3991
+ for col, typ in pipe.dtypes.items()
3992
+ if col and 'geometry' in col.lower() or 'geography' in col.lower()
3993
+ }
3994
+
3995
+ try:
3996
+ df.head(0).to_file(
3997
+ database_path.as_posix(),
3998
+ layer=table,
3999
+ driver='GPKG',
4000
+ index=False,
4001
+ mode=mode,
4002
+ spatial_index=False,
4003
+ )
4004
+ except Exception as e:
4005
+ failed = True
4006
+ create_new = 'at least' in str(e).lower()
4007
+ if not create_new:
4008
+ return False, f"Failed to init table '{table}':\n{e}"
4009
+
4010
+ rename_queries = [
4011
+ (
4012
+ "UPDATE gpkg_geometry_columns\n"
4013
+ f"SET column_name = '{df.active_geometry_name}'\n"
4014
+ f"WHERE table_name = '{table}'\n"
4015
+ " AND column_name = 'geom'"
4016
+ ),
4017
+ ]
4018
+ for col, (geom_typ, srid) in geom_cols_types.items():
4019
+ rename_queries.extend([
4020
+ (
4021
+ "UPDATE gpkg_geometry_columns\n"
4022
+ f"SET geometry_type_name = '{geom_typ.upper()}'\n"
4023
+ f"WHERE table_name = '{table}'\n"
4024
+ f" AND column_name = '{col}'"
4025
+ ),
4026
+ ])
4027
+
4028
+ if table_is_fresh:
4029
+ rename_queries.append(f"DROP TABLE IF EXISTS \"{table}\"")
4030
+
4031
+ if not failed and not create_new:
4032
+ self_sqlite.exec_queries(rename_queries, debug=debug)
4033
+
4034
+ if not create_new:
4035
+ return (
4036
+ True, "Success"
4037
+ ) if not failed else (
4038
+ False, f"Failed to init {self}."
4039
+ )
4040
+
4041
+ tmp_dir_path = SQL_CONN_CACHE_RESOURCES_PATH / tmp_id
4042
+ tmp_dir_path.mkdir(parents=True, exist_ok=False)
4043
+ temp_database_path = tmp_dir_path / f'{tmp_id}.gpkg'
4044
+ tmp_conn = mrsm.get_connector(
4045
+ f"sql:{tmp_id}",
4046
+ flavor='sqlite',
4047
+ database=temp_database_path.as_posix(),
4048
+ )
4049
+ df.head(0).to_file(
4050
+ temp_database_path.as_posix(),
4051
+ layer=table,
4052
+ driver='GPKG',
4053
+ mode='w',
4054
+ spatial_index=False,
4055
+ )
4056
+ tmp_conn.exec_queries(rename_queries, debug=debug)
4057
+ if not table_exists('geometry_columns', self_sqlite, debug=debug):
4058
+ self.exec(
4059
+ "CREATE VIEW geometry_columns AS\n"
4060
+ "SELECT\n"
4061
+ " table_name AS f_table_name,\n"
4062
+ " column_name AS f_geometry_column,\n"
4063
+ " geometry_type_name AS \"type\",\n"
4064
+ " CASE\n"
4065
+ " WHEN z = 0 THEN 'XY'\n"
4066
+ " WHEN z = 1 THEN 'XYZ'\n"
4067
+ " WHEN z = 2 THEN 'XYZ'\n"
4068
+ " END AS coord_dimension,\n"
4069
+ " srs_id AS srid,\n"
4070
+ " 0 AS spatial_index_enabled\n"
4071
+ "FROM gpkg_geometry_columns"
4072
+ )
4073
+
4074
+ tables_definitions = tmp_conn.read(
4075
+ "SELECT name, sql\n"
4076
+ "FROM sqlite_master\n"
4077
+ "WHERE type = 'table'\n"
4078
+ r" AND name LIKE 'gpkg_%' "
4079
+ f"AND name != '{table}'"
4080
+ )
4081
+ tables = tables_definitions['name']
4082
+ tables_cols_types = {
4083
+ tbl: get_table_cols_types(tbl, tmp_conn, flavor='sqlite', debug=debug)
4084
+ for tbl in tables
4085
+ }
4086
+ tables_cols_indices = {
4087
+ tbl: get_table_cols_indices(tbl, tmp_conn, flavor='sqlite', debug=debug)
4088
+ for tbl in tables
4089
+ }
4090
+ tables_pks = {}
4091
+ for tbl, cols_indices in tables_cols_indices.items():
4092
+ for col, indices in cols_indices.items():
4093
+ for ix_dict in indices:
4094
+ if ix_dict.get('type') == 'PRIMARY KEY':
4095
+ tables_pks[tbl] = col
4096
+ break
4097
+
4098
+ if tbl in tables_pks:
4099
+ break
4100
+
4101
+ if tbl in tables_pks:
4102
+ break
4103
+
4104
+ tables_create_queries = {
4105
+ tbl: get_create_table_queries(
4106
+ tables_cols_types[tbl],
4107
+ tbl,
4108
+ flavor='sqlite',
4109
+ primary_key=tables_pks.get(tbl, None),
4110
+ primary_key_db_type=tables_cols_types[tbl].get(tables_pks.get(tbl, None)),
4111
+ _parse_dtypes=False,
4112
+ )
4113
+ for tbl in tables
4114
+ }
4115
+ tables_pipes = {
4116
+ tbl: mrsm.Pipe(
4117
+ f'{tmp_conn}', tbl,
4118
+ temporary=True,
4119
+ instance=str(self_sqlite),
4120
+ target=tbl,
4121
+ static=True,
4122
+ enforce=True,
4123
+ null_indices=False,
4124
+ upsert=False,
4125
+ columns={
4126
+ (col if tables_pks.get(tbl) != col else 'primary'): col
4127
+ for col in tables_cols_indices[tbl]
4128
+ },
4129
+ dtypes={
4130
+ col: (
4131
+ get_pd_type_from_db_type(
4132
+ db_typ
4133
+ if 'datetime' not in db_typ.lower()
4134
+ else 'TIMESTAMPTZ'
4135
+ )
4136
+ )
4137
+ for col, db_typ in tables_cols_types[tbl].items()
4138
+ },
4139
+ parameters={
4140
+ 'sql': f"SELECT * FROM \"{tbl}\"",
4141
+ },
4142
+ )
4143
+ for tbl, cols_types in tables_cols_types.items()
4144
+ }
4145
+
4146
+ init_success = True
4147
+
4148
+ for tbl, create_queries in tables_create_queries.items():
4149
+ result = self_sqlite.exec_queries(create_queries, debug=debug)
4150
+ if not result:
4151
+ warn(f"Failed to create '{table}'.")
4152
+ init_success = False
4153
+
4154
+ pipe = tables_pipes[tbl]
4155
+ sync_success, sync_message = pipe.sync(debug=debug)
4156
+ if not sync_success:
4157
+ warn(f"Failed to migrate table '{tbl}':\n{sync_message}")
4158
+ init_success = False
4159
+
4160
+ if not pipe.indices:
4161
+ continue
4162
+
4163
+ index_success, index_message = pipe.create_indices(debug=debug)
4164
+ if not index_success:
4165
+ warn(f"Failed to create indices for '{tbl}':\n{index_message}")
4166
+ init_success = False
4167
+
4168
+ failed = not init_success
4169
+ _ = connectors.get('sql', {}).pop(tmp_id, None)
4170
+ shutil.rmtree(tmp_dir_path)
4171
+
4172
+ _ = connectors.get('sql', {}).pop(self_sqlite.label, None)
4173
+
4174
+
4175
+ if failed:
4176
+ return False, f"Failed to init {table}."
4177
+
4178
+ return True, "Success"
@@ -946,6 +946,11 @@ def to_sql(
946
946
  )
947
947
  )
948
948
 
949
+ geometry_format = 'wkt' if self.flavor == 'mssql' else (
950
+ 'gpkg_wkb'
951
+ if self.flavor == 'geopackage'
952
+ else 'wkb_hex'
953
+ )
949
954
  for col in geometry_cols:
950
955
  geometry_type, srid = geometry_cols_types_srids.get(col, get_geometry_type_srid())
951
956
  with warnings.catch_warnings():
@@ -953,7 +958,7 @@ def to_sql(
953
958
  df[col] = df[col].apply(
954
959
  functools.partial(
955
960
  serialize_geometry,
956
- geometry_format=('wkt' if self.flavor == 'mssql' else 'wkb_hex'),
961
+ geometry_format=geometry_format,
957
962
  )
958
963
  )
959
964
 
@@ -1347,33 +1352,3 @@ def _cleanup_connections(self) -> None:
1347
1352
  connection.close()
1348
1353
  except Exception:
1349
1354
  pass
1350
-
1351
-
1352
- def _init_geopackage_table(
1353
- self,
1354
- df: 'pd.DataFrame',
1355
- table: str,
1356
- debug: bool = False,
1357
- ) -> SuccessTuple:
1358
- """
1359
- Initialize the geopackage schema tables from a DataFrame.
1360
- """
1361
- import pathlib
1362
- database = self.__dict__.get('database', self.parse_uri(self.URI).get('database', None))
1363
- if not database:
1364
- return False, f"Could not determine database for '{self}'."
1365
-
1366
- database_path = pathlib.Path(database)
1367
- mode = 'w' if not database_path.exists() else 'a'
1368
-
1369
- try:
1370
- df.head(0).to_file(
1371
- database_path.as_posix(),
1372
- layer=table,
1373
- driver='GPKG',
1374
- index=False,
1375
- mode=mode,
1376
- )
1377
- except Exception as e:
1378
- return False, f"Failed to init table '{table}':\n{e}"
1379
- return True, "Success"
@@ -10,6 +10,7 @@ import traceback
10
10
  import json
11
11
  import uuid
12
12
  import time
13
+ import struct
13
14
  from datetime import timezone, datetime, date, timedelta
14
15
  from decimal import Decimal, Context, InvalidOperation, ROUND_HALF_UP
15
16
 
@@ -360,6 +361,14 @@ def attempt_cast_to_geometry(value: Any) -> Any:
360
361
  except Exception:
361
362
  return value
362
363
 
364
+ value_is_gpkg = geometry_is_gpkg(value)
365
+ if value_is_gpkg:
366
+ try:
367
+ wkb_data, _, _ = gpkg_wkb_to_wkb(value)
368
+ return shapely_wkb.loads(wkb_data)
369
+ except Exception:
370
+ return value
371
+
363
372
  value_is_wkt = geometry_is_wkt(value)
364
373
  if value_is_wkt is None:
365
374
  return value
@@ -405,6 +414,56 @@ def geometry_is_wkt(value: Union[str, bytes]) -> Union[bool, None]:
405
414
  return None
406
415
 
407
416
 
417
+ def geometry_is_gpkg(value: bytes) -> bool:
418
+ """
419
+ Return whether the input `value` is formatted as GeoPackage WKB.
420
+ """
421
+ if not isinstance(value, bytes) or len(value) < 2:
422
+ return False
423
+
424
+ return value[0:2] == b'GP'
425
+
426
+ def gpkg_wkb_to_wkb(gpkg_wkb_bytes: bytes) -> Tuple[bytes, int, bytes]:
427
+ """
428
+ Converts GeoPackage WKB to standard WKB by removing the header.
429
+
430
+ Parameters
431
+ ----------
432
+ gpkg_wkb_bytes: bytes
433
+ The GeoPackage WKB byte string.
434
+
435
+ Returns
436
+ -------
437
+ A tuple containing the standard WKB bytes, SRID, and flags.
438
+ """
439
+ magic_number = gpkg_wkb_bytes[0:2]
440
+ if magic_number != b'GP':
441
+ raise ValueError("Invalid GeoPackage WKB header: missing magic number.")
442
+
443
+ try:
444
+ header = gpkg_wkb_bytes[0:8]
445
+ header_vals = struct.unpack('<ccBBi', header)
446
+ flags = header_vals[-2]
447
+ srid = header_vals[-1]
448
+ except struct.error:
449
+ header = gpkg_wkb_bytes[0:6]
450
+ header_vals = struct.unpack('<ccBBh', header)
451
+ flags = header_vals[-2]
452
+ srid = header_vals[-1]
453
+
454
+ envelope_type = (flags >> 1) & 0x07
455
+ envelope_sizes = {
456
+ 0: 0,
457
+ 1: 32,
458
+ 2: 48,
459
+ 3: 48,
460
+ 4: 64,
461
+ }
462
+ header_length = 8 + envelope_sizes.get(envelope_type, 0)
463
+ standard_wkb_bytes = gpkg_wkb_bytes[header_length:]
464
+ return standard_wkb_bytes, srid, flags
465
+
466
+
408
467
  def value_is_null(value: Any) -> bool:
409
468
  """
410
469
  Determine if a value is a null-like string.
@@ -690,9 +749,9 @@ def serialize_geometry(
690
749
  geom: Any,
691
750
  geometry_format: str = 'wkb_hex',
692
751
  srid: Optional[int] = None,
693
- ) -> Union[str, Dict[str, Any], None]:
752
+ ) -> Union[str, Dict[str, Any], bytes, None]:
694
753
  """
695
- Serialize geometry data as a hex-encoded well-known-binary string.
754
+ Serialize geometry data as WKB, WKB (hex), GPKG-WKB, WKT, or GeoJSON.
696
755
 
697
756
  Parameters
698
757
  ----------
@@ -701,20 +760,20 @@ def serialize_geometry(
701
760
 
702
761
  geometry_format: str, default 'wkb_hex'
703
762
  The serialization format for geometry data.
704
- Accepted formats are `wkb_hex` (well-known binary hex string),
705
- `wkt` (well-known text), and `geojson`.
763
+ Accepted formats are `wkb`, `wkb_hex`, `wkt`, `geojson`, and `gpkg_wkb`.
706
764
 
707
765
  srid: Optional[int], default None
708
766
  If provided, use this as the source CRS when serializing to GeoJSON.
709
767
 
710
768
  Returns
711
769
  -------
712
- A string containing the geometry data.
770
+ A string containing the geometry data, or bytes, or a dictionary, or None.
713
771
  """
714
772
  if value_is_null(geom):
715
773
  return None
716
- shapely, shapely_ops, pyproj = mrsm.attempt_import(
717
- 'shapely', 'shapely.ops', 'pyproj',
774
+
775
+ shapely, shapely_ops, pyproj, np = mrsm.attempt_import(
776
+ 'shapely', 'shapely.ops', 'pyproj', 'numpy',
718
777
  lazy=False,
719
778
  )
720
779
  if geometry_format == 'geojson':
@@ -724,12 +783,31 @@ def serialize_geometry(
724
783
  geojson_str = shapely.to_geojson(geom)
725
784
  return json.loads(geojson_str)
726
785
 
727
- if hasattr(geom, 'wkb_hex'):
728
- if geometry_format == "wkb_hex":
729
- return shapely.to_wkb(geom, hex=True, include_srid=True)
730
- return shapely.to_wkt(geom)
786
+ if not hasattr(geom, 'wkb_hex'):
787
+ return str(geom)
788
+
789
+ byte_order = 1 if np.little_endian else 0
790
+
791
+ if geometry_format.startswith("wkb"):
792
+ return shapely.to_wkb(geom, hex=(geometry_format=="wkb_hex"), include_srid=True)
793
+ elif geometry_format == 'gpkg_wkb':
794
+ wkb_data = shapely.to_wkb(geom, hex=False, byte_order=byte_order)
795
+ flags = (
796
+ ((byte_order & 0x01) | (0x20))
797
+ if geom.is_empty
798
+ else (byte_order & 0x01)
799
+ )
800
+ srid_val = srid or -1
801
+ header = struct.pack(
802
+ '<ccBBi',
803
+ b'G', b'P',
804
+ 0,
805
+ flags,
806
+ srid_val
807
+ )
808
+ return header + wkb_data
731
809
 
732
- return str(geom)
810
+ return shapely.to_wkt(geom)
733
811
 
734
812
 
735
813
  def deserialize_geometry(geom_wkb: Union[str, bytes]):
@@ -635,7 +635,7 @@ PD_TO_DB_DTYPES_FLAVORS: Dict[str, Dict[str, str]] = {
635
635
  'mssql': 'NVARCHAR(MAX)',
636
636
  'oracle': 'NVARCHAR2(2000)',
637
637
  'sqlite': 'TEXT',
638
- 'geopackage': 'GEOMETRY',
638
+ 'geopackage': 'BLOB',
639
639
  'duckdb': 'TEXT',
640
640
  'citus': 'TEXT',
641
641
  'cockroachdb': 'TEXT',
@@ -651,7 +651,7 @@ PD_TO_DB_DTYPES_FLAVORS: Dict[str, Dict[str, str]] = {
651
651
  'mssql': 'NVARCHAR(MAX)',
652
652
  'oracle': 'NVARCHAR2(2000)',
653
653
  'sqlite': 'TEXT',
654
- 'geopackage': 'TEXT',
654
+ 'geopackage': 'BLOB',
655
655
  'duckdb': 'TEXT',
656
656
  'citus': 'TEXT',
657
657
  'cockroachdb': 'TEXT',
@@ -1133,7 +1133,7 @@ PD_TO_SQLALCHEMY_DTYPES_FLAVORS: Dict[str, Dict[str, str]] = {
1133
1133
  'mssql': 'UnicodeText',
1134
1134
  'oracle': 'UnicodeText',
1135
1135
  'sqlite': 'UnicodeText',
1136
- 'geopackage': 'UnicodeText',
1136
+ 'geopackage': 'LargeBinary',
1137
1137
  'duckdb': 'UnicodeText',
1138
1138
  'citus': 'UnicodeText',
1139
1139
  'cockroachdb': 'UnicodeText',
@@ -2146,6 +2146,7 @@ def get_create_table_queries(
2146
2146
  primary_key_db_type: Optional[str] = None,
2147
2147
  autoincrement: bool = False,
2148
2148
  datetime_column: Optional[str] = None,
2149
+ _parse_dtypes: bool = True,
2149
2150
  ) -> List[str]:
2150
2151
  """
2151
2152
  Return a query to create a new table from a `SELECT` query or a `dtypes` dictionary.
@@ -2179,6 +2180,10 @@ def get_create_table_queries(
2179
2180
  If provided, include this column in the primary key.
2180
2181
  Applicable to TimescaleDB only.
2181
2182
 
2183
+ _parse_dtypes: bool, default True
2184
+ If `True`, cast Pandas dtypes to SQL dtypes.
2185
+ Otherwise pass through the given value directly.
2186
+
2182
2187
  Returns
2183
2188
  -------
2184
2189
  A `CREATE TABLE` (or `SELECT INTO`) query for the database flavor.
@@ -2200,6 +2205,7 @@ def get_create_table_queries(
2200
2205
  primary_key_db_type=primary_key_db_type,
2201
2206
  autoincrement=(autoincrement and flavor not in SKIP_AUTO_INCREMENT_FLAVORS),
2202
2207
  datetime_column=datetime_column,
2208
+ _parse_dtypes=_parse_dtypes,
2203
2209
  )
2204
2210
 
2205
2211
 
@@ -2212,6 +2218,7 @@ def _get_create_table_query_from_dtypes(
2212
2218
  primary_key_db_type: Optional[str] = None,
2213
2219
  autoincrement: bool = False,
2214
2220
  datetime_column: Optional[str] = None,
2221
+ _parse_dtypes: bool = True,
2215
2222
  ) -> List[str]:
2216
2223
  """
2217
2224
  Create a new table from a `dtypes` dictionary.
@@ -2228,12 +2235,22 @@ def _get_create_table_query_from_dtypes(
2228
2235
  (
2229
2236
  primary_key,
2230
2237
  get_db_type_from_pd_type(dtypes.get(primary_key, 'int') or 'int', flavor=flavor)
2238
+ ) if _parse_dtypes else (
2239
+ primary_key,
2240
+ dtypes.get(primary_key, 'INT') or 'INT'
2231
2241
  )
2232
2242
  ]
2233
2243
  if primary_key
2234
2244
  else []
2235
2245
  ) + [
2236
- (col, get_db_type_from_pd_type(typ, flavor=flavor))
2246
+ (
2247
+ col,
2248
+ (
2249
+ get_db_type_from_pd_type(typ, flavor=flavor)
2250
+ if _parse_dtypes
2251
+ else typ
2252
+ )
2253
+ )
2237
2254
  for col, typ in dtypes.items()
2238
2255
  if col != primary_key
2239
2256
  ]
@@ -2311,6 +2328,7 @@ def _get_create_table_query_from_cte(
2311
2328
  primary_key_db_type: Optional[str] = None,
2312
2329
  autoincrement: bool = False,
2313
2330
  datetime_column: Optional[str] = None,
2331
+ _parse_dtypes=None,
2314
2332
  ) -> List[str]:
2315
2333
  """
2316
2334
  Create a new table from a CTE query.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meerschaum
3
- Version: 3.0.8
3
+ Version: 3.0.9
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Author-email: Bennett Meares <bennett.meares@gmail.com>
6
6
  Maintainer-email: Bennett Meares <bennett.meares@gmail.com>
File without changes
File without changes
File without changes
File without changes