meerschaum 2.6.0.dev1__py3-none-any.whl → 2.6.1__py3-none-any.whl

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 (36) hide show
  1. meerschaum/api/dash/pages/login.py +17 -17
  2. meerschaum/api/dash/pipes.py +13 -4
  3. meerschaum/api/routes/_pipes.py +162 -136
  4. meerschaum/config/_version.py +1 -1
  5. meerschaum/config/static/__init__.py +1 -0
  6. meerschaum/connectors/api/_APIConnector.py +1 -0
  7. meerschaum/connectors/api/_pipes.py +46 -13
  8. meerschaum/connectors/sql/_SQLConnector.py +4 -3
  9. meerschaum/connectors/sql/_fetch.py +4 -2
  10. meerschaum/connectors/sql/_pipes.py +496 -148
  11. meerschaum/connectors/sql/_sql.py +37 -16
  12. meerschaum/connectors/valkey/_ValkeyConnector.py +3 -2
  13. meerschaum/connectors/valkey/_pipes.py +13 -5
  14. meerschaum/core/Pipe/__init__.py +20 -0
  15. meerschaum/core/Pipe/_attributes.py +179 -9
  16. meerschaum/core/Pipe/_clear.py +10 -8
  17. meerschaum/core/Pipe/_copy.py +2 -0
  18. meerschaum/core/Pipe/_data.py +57 -28
  19. meerschaum/core/Pipe/_deduplicate.py +30 -28
  20. meerschaum/core/Pipe/_dtypes.py +12 -2
  21. meerschaum/core/Pipe/_fetch.py +11 -9
  22. meerschaum/core/Pipe/_sync.py +24 -7
  23. meerschaum/core/Pipe/_verify.py +51 -48
  24. meerschaum/utils/dataframe.py +16 -8
  25. meerschaum/utils/dtypes/__init__.py +9 -1
  26. meerschaum/utils/dtypes/sql.py +32 -6
  27. meerschaum/utils/misc.py +8 -8
  28. meerschaum/utils/sql.py +485 -16
  29. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/METADATA +1 -1
  30. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/RECORD +36 -36
  31. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/LICENSE +0 -0
  32. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/NOTICE +0 -0
  33. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/WHEEL +0 -0
  34. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/entry_points.txt +0 -0
  35. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/top_level.txt +0 -0
  36. {meerschaum-2.6.0.dev1.dist-info → meerschaum-2.6.1.dist-info}/zip-safe +0 -0
@@ -367,6 +367,7 @@ def get_pipe_data(
367
367
 
368
368
  from meerschaum.utils.packages import import_pandas
369
369
  from meerschaum.utils.dataframe import parse_df_datetimes, add_missing_cols_to_df
370
+ from meerschaum.utils.dtypes import are_dtypes_equal
370
371
  pd = import_pandas()
371
372
  try:
372
373
  df = pd.read_json(StringIO(response.text))
@@ -382,16 +383,17 @@ def get_pipe_data(
382
383
  ignore_cols = [
383
384
  col
384
385
  for col, dtype in pipe.dtypes.items()
385
- if 'datetime' not in str(dtype)
386
+ if not are_dtypes_equal(str(dtype), 'datetime')
386
387
  ],
387
- debug = debug,
388
+ strip_timezone=(pipe.tzinfo is None),
389
+ debug=debug,
388
390
  )
389
391
  return df
390
392
 
391
393
 
392
394
  def get_pipe_id(
393
395
  self,
394
- pipe: meerschuam.Pipe,
396
+ pipe: mrsm.Pipe,
395
397
  debug: bool = False,
396
398
  ) -> int:
397
399
  """Get a Pipe's ID from the API."""
@@ -413,7 +415,7 @@ def get_pipe_id(
413
415
 
414
416
  def get_pipe_attributes(
415
417
  self,
416
- pipe: meerschaum.Pipe,
418
+ pipe: mrsm.Pipe,
417
419
  debug: bool = False,
418
420
  ) -> Dict[str, Any]:
419
421
  """Get a Pipe's attributes from the API
@@ -439,7 +441,7 @@ def get_pipe_attributes(
439
441
 
440
442
  def get_sync_time(
441
443
  self,
442
- pipe: 'meerschaum.Pipe',
444
+ pipe: mrsm.Pipe,
443
445
  params: Optional[Dict[str, Any]] = None,
444
446
  newest: bool = True,
445
447
  debug: bool = False,
@@ -669,11 +671,11 @@ def clear_pipe(
669
671
  kw.pop('force', None)
670
672
  return self.do_action_legacy(
671
673
  ['clear', 'pipes'],
672
- connector_keys = pipe.connector_keys,
673
- metric_keys = pipe.metric_key,
674
- location_keys = pipe.location_key,
675
- force = True,
676
- debug = debug,
674
+ connector_keys=pipe.connector_keys,
675
+ metric_keys=pipe.metric_key,
676
+ location_keys=pipe.location_key,
677
+ force=True,
678
+ debug=debug,
677
679
  **kw
678
680
  )
679
681
 
@@ -690,7 +692,7 @@ def get_pipe_columns_types(
690
692
  ----------
691
693
  pipe: meerschaum.Pipe
692
694
  The pipe whose columns to be queried.
693
-
695
+
694
696
  Returns
695
697
  -------
696
698
  A dictionary mapping column names to their database types.
@@ -707,11 +709,42 @@ def get_pipe_columns_types(
707
709
  r_url = pipe_r_url(pipe) + '/columns/types'
708
710
  response = self.get(
709
711
  r_url,
710
- debug = debug
712
+ debug=debug
713
+ )
714
+ j = response.json()
715
+ if isinstance(j, dict) and 'detail' in j and len(j.keys()) == 1:
716
+ warn(j['detail'])
717
+ return None
718
+ if not isinstance(j, dict):
719
+ warn(response.text)
720
+ return None
721
+ return j
722
+
723
+
724
+ def get_pipe_columns_indices(
725
+ self,
726
+ pipe: mrsm.Pipe,
727
+ debug: bool = False,
728
+ ) -> Union[Dict[str, str], None]:
729
+ """
730
+ Fetch the index information for a pipe.
731
+
732
+ Parameters
733
+ ----------
734
+ pipe: mrsm.Pipe
735
+ The pipe whose columns to be queried.
736
+
737
+ Returns
738
+ -------
739
+ A dictionary mapping column names to a list of associated index information.
740
+ """
741
+ r_url = pipe_r_url(pipe) + '/columns/indices'
742
+ response = self.get(
743
+ r_url,
744
+ debug=debug
711
745
  )
712
746
  j = response.json()
713
747
  if isinstance(j, dict) and 'detail' in j and len(j.keys()) == 1:
714
- from meerschaum.utils.warnings import warn
715
748
  warn(j['detail'])
716
749
  return None
717
750
  if not isinstance(j, dict):
@@ -67,6 +67,8 @@ class SQLConnector(Connector):
67
67
  get_pipe_columns_types,
68
68
  get_to_sql_dtype,
69
69
  get_pipe_schema,
70
+ create_pipe_table_from_df,
71
+ get_pipe_columns_indices,
70
72
  )
71
73
  from ._plugins import (
72
74
  register_plugin,
@@ -141,9 +143,9 @@ class SQLConnector(Connector):
141
143
  if uri.startswith('postgres') and not uri.startswith('postgresql'):
142
144
  uri = uri.replace('postgres', 'postgresql', 1)
143
145
  if uri.startswith('postgresql') and not uri.startswith('postgresql+'):
144
- uri = uri.replace('postgresql://', 'postgresql+psycopg', 1)
146
+ uri = uri.replace('postgresql://', 'postgresql+psycopg://', 1)
145
147
  if uri.startswith('timescaledb://'):
146
- uri = uri.replace('timescaledb://', 'postgresql://', 1)
148
+ uri = uri.replace('timescaledb://', 'postgresql+psycopg://', 1)
147
149
  flavor = 'timescaledb'
148
150
  kw['uri'] = uri
149
151
  from_uri_params = self.from_uri(kw['uri'], as_dict=True)
@@ -155,7 +157,6 @@ class SQLConnector(Connector):
155
157
  if flavor:
156
158
  kw['flavor'] = flavor
157
159
 
158
-
159
160
  ### set __dict__ in base class
160
161
  super().__init__(
161
162
  'sql',
@@ -90,16 +90,18 @@ def fetch(
90
90
  )
91
91
  ### if sqlite, parse for datetimes
92
92
  if not as_hook_results and self.flavor == 'sqlite':
93
- from meerschaum.utils.misc import parse_df_datetimes
93
+ from meerschaum.utils.dataframe import parse_df_datetimes
94
+ from meerschaum.utils.dtypes import are_dtypes_equal
94
95
  ignore_cols = [
95
96
  col
96
97
  for col, dtype in pipe.dtypes.items()
97
- if 'datetime' not in str(dtype)
98
+ if not are_dtypes_equal(str(dtype), 'datetime')
98
99
  ]
99
100
  return (
100
101
  parse_df_datetimes(
101
102
  chunk,
102
103
  ignore_cols=ignore_cols,
104
+ strip_timezone=(pipe.tzinfo is None),
103
105
  debug=debug,
104
106
  )
105
107
  for chunk in chunks