meerschaum 2.6.14__py3-none-any.whl → 2.6.16__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.
@@ -54,10 +54,9 @@ def _bootstrap_pipes(
54
54
  """
55
55
  from meerschaum import get_pipes
56
56
  from meerschaum.config import get_config
57
- from meerschaum.utils.warnings import info, warn, error
58
- from meerschaum.utils.debug import dprint
57
+ from meerschaum.utils.warnings import info, warn
59
58
  from meerschaum.utils.prompt import yes_no, prompt, choose
60
- from meerschaum.connectors.parse import is_valid_connector_keys, parse_instance_keys
59
+ from meerschaum.connectors.parse import parse_instance_keys
61
60
  from meerschaum.utils.misc import get_connector_labels
62
61
  from meerschaum.utils.formatting._shell import clear_screen
63
62
 
@@ -102,7 +101,7 @@ def _bootstrap_pipes(
102
101
  ### Get the connector.
103
102
  new_label = 'New'
104
103
  info(
105
- f"To create a pipe without explicitly using a connector, "
104
+ "To create a pipe without explicitly using a connector, "
106
105
  + "use the `register pipes` command.\n"
107
106
  )
108
107
  try:
@@ -133,7 +132,7 @@ def _bootstrap_pipes(
133
132
  break
134
133
  elif isinstance(tup[0], bool) and not tup[0]:
135
134
  return abort_tuple
136
- warn(f"Please register a new connector or press CTRL+C to cancel.", stack=False)
135
+ warn("Please register a new connector or press CTRL+C to cancel.", stack=False)
137
136
  connector_keys = [ck]
138
137
 
139
138
  ### Get the metric.
@@ -142,9 +141,9 @@ def _bootstrap_pipes(
142
141
  clear_screen(debug=debug)
143
142
  try:
144
143
  mk = prompt(
145
- f"What kind of data is this?\n\n" +
146
- f" The metric is the label for the contents of the pipe.\n" +
147
- f" For example, 'weather' might be a metric for weather station data.\n\n" +
144
+ "What kind of data is this?\n\n" +
145
+ " The metric is the label for the contents of the pipe.\n" +
146
+ " For example, 'weather' might be a metric for weather station data.\n\n" +
148
147
  f" {get_config('formatting', 'emoji', 'metric')} Metric:"
149
148
  )
150
149
  except KeyboardInterrupt:
@@ -224,6 +223,7 @@ def _bootstrap_pipes(
224
223
 
225
224
  return (successes > 0), msg
226
225
 
226
+
227
227
  def _bootstrap_connectors(
228
228
  action: Optional[List[str]] = None,
229
229
  connector_keys: Optional[List[str]] = None,
@@ -237,7 +237,6 @@ def _bootstrap_connectors(
237
237
  """
238
238
  Prompt the user for the details necessary to create a Connector.
239
239
  """
240
- from meerschaum.connectors.parse import is_valid_connector_keys
241
240
  from meerschaum.connectors import (
242
241
  connectors,
243
242
  get_connector,
@@ -38,7 +38,6 @@ def _complete_copy(
38
38
  """
39
39
  Override the default Meerschaum `complete_` function.
40
40
  """
41
- from meerschaum.actions.edit import _complete_edit_config
42
41
  if action is None:
43
42
  action = []
44
43
 
@@ -71,7 +70,7 @@ def _copy_pipes(
71
70
  """
72
71
  from meerschaum import get_pipes, Pipe
73
72
  from meerschaum.utils.prompt import prompt, yes_no
74
- from meerschaum.utils.warnings import warn, info
73
+ from meerschaum.utils.warnings import warn
75
74
  from meerschaum.utils.formatting import print_tuple
76
75
  from meerschaum.utils.formatting._shell import clear_screen
77
76
  pipes = get_pipes(as_list=True, **kw)
@@ -110,7 +109,9 @@ def _copy_pipes(
110
109
  f"Do you want to copy data from {p} into {_new_pipe}?\n\n"
111
110
  + "If you specified `--begin`, `--end` or `--params`, data will be filtered."
112
111
  ),
113
- noask=noask, yes=yes
112
+ noask=noask,
113
+ yes=yes,
114
+ default='n',
114
115
  )
115
116
  ):
116
117
  _new_pipe.sync(
@@ -131,7 +131,6 @@ default_pipes_config = {
131
131
  'parameters': {
132
132
  'columns': {
133
133
  'datetime': None,
134
- 'id': None,
135
134
  },
136
135
  'fetch': {
137
136
  'backtrack_minutes': 1440,
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.6.14"
5
+ __version__ = "2.6.16"
@@ -284,15 +284,15 @@ def set_pipe_query(pipe: mrsm.Pipe, query: str) -> None:
284
284
  - query
285
285
  - sql
286
286
  """
287
- if pipe.parameters.get('fetch', {}).get('definition', None):
287
+ if 'fetch' in pipe.parameters and 'definition' in pipe.parameters['fetch']:
288
288
  if pipe.parameters.get('fetch', None) is None:
289
289
  pipe.parameters['fetch'] = {}
290
290
  dict_to_set = pipe.parameters['fetch']
291
291
  key_to_set = 'definition'
292
- elif pipe.parameters.get('definition', None):
292
+ elif 'definition' in pipe.parameters:
293
293
  dict_to_set = pipe.parameters
294
294
  key_to_set = 'definition'
295
- elif pipe.parameters.get('query', None):
295
+ elif 'query' in pipe.parameters:
296
296
  dict_to_set = pipe.parameters
297
297
  key_to_set = 'query'
298
298
  else:
@@ -1770,8 +1770,8 @@ def sync_pipe_inplace(
1770
1770
  self,
1771
1771
  pipe: 'mrsm.Pipe',
1772
1772
  params: Optional[Dict[str, Any]] = None,
1773
- begin: Optional[datetime] = None,
1774
- end: Optional[datetime] = None,
1773
+ begin: Union[datetime, int, None] = None,
1774
+ end: Union[datetime, int, None] = None,
1775
1775
  chunksize: Optional[int] = -1,
1776
1776
  check_existing: bool = True,
1777
1777
  debug: bool = False,
@@ -1790,11 +1790,11 @@ def sync_pipe_inplace(
1790
1790
  Optional params dictionary to build the `WHERE` clause.
1791
1791
  See `meerschaum.utils.sql.build_where`.
1792
1792
 
1793
- begin: Optional[datetime], default None
1793
+ begin: Union[datetime, int, None], default None
1794
1794
  Optionally specify the earliest datetime to search for data.
1795
1795
  Defaults to `None`.
1796
1796
 
1797
- end: Optional[datetime], default None
1797
+ end: Union[datetime, int, None], default None
1798
1798
  Optionally specify the latest datetime to search for data.
1799
1799
  Defaults to `None`.
1800
1800
 
@@ -1834,7 +1834,7 @@ def sync_pipe_inplace(
1834
1834
  session_execute,
1835
1835
  update_queries,
1836
1836
  )
1837
- from meerschaum.utils.dtypes import coerce_timezone, are_dtypes_equal
1837
+ from meerschaum.utils.dtypes import are_dtypes_equal
1838
1838
  from meerschaum.utils.dtypes.sql import (
1839
1839
  get_pd_type_from_db_type,
1840
1840
  )
@@ -1842,7 +1842,7 @@ def sync_pipe_inplace(
1842
1842
 
1843
1843
  transact_id = generate_password(3)
1844
1844
  def get_temp_table_name(label: str) -> str:
1845
- temp_prefix = '##' if self.flavor != 'oracle' else ''
1845
+ temp_prefix = '##' if self.flavor != 'oracle' else '_'
1846
1846
  return temp_prefix + transact_id + '_' + label + '_' + pipe.target
1847
1847
 
1848
1848
  internal_schema = self.internal_schema
@@ -1875,7 +1875,6 @@ def sync_pipe_inplace(
1875
1875
  autoincrement = pipe.parameters.get('autoincrement', False)
1876
1876
  dt_col = pipe.columns.get('datetime', None)
1877
1877
  dt_col_name = sql_item_name(dt_col, self.flavor, None) if dt_col else None
1878
- dt_typ = pipe.dtypes.get(dt_col, 'datetime64[ns, UTC]') if dt_col else None
1879
1878
 
1880
1879
  def clean_up_temp_tables(ready_to_drop: bool = False):
1881
1880
  log_success, log_msg = self._log_temporary_tables_creation(
@@ -2008,14 +2007,14 @@ def sync_pipe_inplace(
2008
2007
  ],
2009
2008
  with_results=True,
2010
2009
  debug=debug,
2011
- ) if not upsert else ((True, "Success"), None)
2010
+ ) if dt_col and not upsert else ((True, "Success"), None)
2012
2011
  if not new_dt_bounds_success:
2013
2012
  return (
2014
2013
  new_dt_bounds_success,
2015
2014
  f"Could not determine in-place datetime bounds:\n{new_dt_bounds_msg}"
2016
2015
  )
2017
2016
 
2018
- if not upsert:
2017
+ if dt_col and not upsert:
2019
2018
  begin, end = new_dt_bounds_results[0].fetchone()
2020
2019
 
2021
2020
  backtrack_def = self.get_pipe_data_query(
@@ -2352,18 +2351,9 @@ def get_sync_time(
2352
2351
  table = sql_item_name(pipe.target, self.flavor, self.get_pipe_schema(pipe))
2353
2352
 
2354
2353
  dt_col = pipe.columns.get('datetime', None)
2355
- dt_type = pipe.dtypes.get(dt_col, 'datetime64[ns, UTC]')
2356
- if not dt_col:
2357
- _dt = pipe.guess_datetime()
2358
- dt = sql_item_name(_dt, self.flavor, None) if _dt else None
2359
- is_guess = True
2360
- else:
2361
- _dt = dt_col
2362
- dt = sql_item_name(_dt, self.flavor, None)
2363
- is_guess = False
2364
-
2365
- if _dt is None:
2354
+ if dt_col is None:
2366
2355
  return None
2356
+ dt_col_name = sql_item_name(dt_col, self.flavor, None)
2367
2357
 
2368
2358
  ASC_or_DESC = "DESC" if newest else "ASC"
2369
2359
  existing_cols = pipe.get_columns_types(debug=debug)
@@ -2373,16 +2363,17 @@ def get_sync_time(
2373
2363
 
2374
2364
  ### If no bounds are provided for the datetime column,
2375
2365
  ### add IS NOT NULL to the WHERE clause.
2376
- if _dt not in valid_params:
2377
- valid_params[_dt] = '_None'
2366
+ if dt_col not in valid_params:
2367
+ valid_params[dt_col] = '_None'
2378
2368
  where = "" if not valid_params else build_where(valid_params, self)
2379
- q = f"SELECT {dt}\nFROM {table}{where}\nORDER BY {dt} {ASC_or_DESC}\nLIMIT 1"
2369
+ q = f"SELECT {dt_col_name}\nFROM {table}{where}\nORDER BY {dt_col_name} {ASC_or_DESC}\nLIMIT 1"
2380
2370
  if self.flavor == 'mssql':
2381
- q = f"SELECT TOP 1 {dt}\nFROM {table}{where}\nORDER BY {dt} {ASC_or_DESC}"
2371
+ q = f"SELECT TOP 1 {dt_col_name}\nFROM {table}{where}\nORDER BY {dt_col_name} {ASC_or_DESC}"
2382
2372
  elif self.flavor == 'oracle':
2383
2373
  q = (
2384
2374
  "SELECT * FROM (\n"
2385
- + f" SELECT {dt}\nFROM {table}{where}\n ORDER BY {dt} {ASC_or_DESC}\n"
2375
+ + f" SELECT {dt_col_name}\nFROM {table}{where}\n "
2376
+ + f"ORDER BY {dt_col_name} {ASC_or_DESC}\n"
2386
2377
  + ") WHERE ROWNUM = 1"
2387
2378
  )
2388
2379
 
@@ -612,24 +612,34 @@ def target(self) -> str:
612
612
  - `target_table_name`
613
613
  """
614
614
  if 'target' not in self.parameters:
615
- target = self._target_legacy()
615
+ default_target = self._target_legacy()
616
+ default_targets = {default_target}
616
617
  potential_keys = ('target_name', 'target_table', 'target_table_name')
618
+ _target = None
617
619
  for k in potential_keys:
618
620
  if k in self.parameters:
619
- target = self.parameters[k]
621
+ _target = self.parameters[k]
620
622
  break
621
623
 
624
+ _target = _target or default_target
625
+
622
626
  if self.instance_connector.type == 'sql':
623
627
  from meerschaum.utils.sql import truncate_item_name
624
- truncated_target = truncate_item_name(target, self.instance_connector.flavor)
625
- if truncated_target != target:
626
- warn(
627
- f"The target '{target}' is too long for '{self.instance_connector.flavor}', "
628
- + f"will use {truncated_target} instead."
629
- )
630
- target = truncated_target
631
-
632
- self.target = target
628
+ truncated_target = truncate_item_name(_target, self.instance_connector.flavor)
629
+ default_targets.add(truncated_target)
630
+ warned_target = self.__dict__.get('_warned_target', False)
631
+ if truncated_target != _target and not warned_target:
632
+ if not warned_target:
633
+ warn(
634
+ f"The target '{_target}' is too long for '{self.instance_connector.flavor}', "
635
+ + f"will use {truncated_target} instead."
636
+ )
637
+ self.__dict__['_warned_target'] = True
638
+ _target = truncated_target
639
+
640
+ if _target in default_targets:
641
+ return _target
642
+ self.target = _target
633
643
  return self.parameters['target']
634
644
 
635
645
 
@@ -7,17 +7,18 @@ Attempt to create a pipe's requirements in one method.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
- from meerschaum.utils.typing import SuccessTuple, Optional, Dict, Any
10
+ from meerschaum.utils.typing import SuccessTuple, Dict, Any
11
+
11
12
 
12
13
  def bootstrap(
13
- self,
14
- debug: bool = False,
15
- yes: bool = False,
16
- force: bool = False,
17
- noask: bool = False,
18
- shell: bool = False,
19
- **kw
20
- ) -> SuccessTuple:
14
+ self,
15
+ debug: bool = False,
16
+ yes: bool = False,
17
+ force: bool = False,
18
+ noask: bool = False,
19
+ shell: bool = False,
20
+ **kw
21
+ ) -> SuccessTuple:
21
22
  """
22
23
  Prompt the user to create a pipe's requirements all from one method.
23
24
  This method shouldn't be used in any automated scripts because it interactively
@@ -46,7 +47,7 @@ def bootstrap(
46
47
 
47
48
  """
48
49
 
49
- from meerschaum.utils.warnings import warn, info, error
50
+ from meerschaum.utils.warnings import info
50
51
  from meerschaum.utils.prompt import prompt, yes_no
51
52
  from meerschaum.utils.formatting import pprint
52
53
  from meerschaum.config import get_config
@@ -74,8 +75,8 @@ def bootstrap(
74
75
  f"\n Press [Enter] to register {self} with the above configuration:",
75
76
  icon = False
76
77
  )
77
- except KeyboardInterrupt as e:
78
- return False, f"Aborting bootstrapping {self}."
78
+ except KeyboardInterrupt:
79
+ return False, f"Aborted bootstrapping {self}."
79
80
 
80
81
  with Venv(get_connector_plugin(self.instance_connector)):
81
82
  register_tuple = self.instance_connector.register_pipe(self, debug=debug)
@@ -119,7 +120,7 @@ def bootstrap(
119
120
 
120
121
  print_tuple((True, f"Finished bootstrapping {self}!"))
121
122
  info(
122
- f"You can edit this pipe later with `edit pipes` "
123
+ "You can edit this pipe later with `edit pipes` "
123
124
  + "or set the definition with `edit pipes definition`.\n"
124
125
  + " To sync data into your pipe, run `sync pipes`."
125
126
  )
@@ -128,7 +129,7 @@ def bootstrap(
128
129
 
129
130
 
130
131
  def _get_parameters(pipe, debug: bool = False) -> Dict[str, Any]:
131
- from meerschaum.utils.prompt import prompt, yes_no
132
+ from meerschaum.utils.prompt import prompt
132
133
  from meerschaum.utils.warnings import warn, info
133
134
  from meerschaum.config import get_config
134
135
  from meerschaum.config._patch import apply_patch_to_config
@@ -139,36 +140,22 @@ def _get_parameters(pipe, debug: bool = False) -> Dict[str, Any]:
139
140
  _types_defaults = {
140
141
  'sql': {
141
142
  'fetch': {
143
+ 'backtrack_minutes': get_config(
144
+ 'pipes', 'parameters', 'fetch', 'backtrack_minutes'
145
+ ),
142
146
  'definition': None,
143
147
  },
144
- 'parents': [
145
- {
146
- 'connector': None,
147
- 'metric': None,
148
- 'location': None,
149
- 'instance': None,
150
- },
151
- ],
148
+ 'verify': {
149
+ 'chunk_minutes': get_config('pipes', 'parameters', 'verify', 'chunk_minutes'),
150
+ },
152
151
  },
153
152
  'api': {
154
- 'fetch': {
155
- 'connector': None,
156
- 'metric': None,
157
- 'location': None,
158
- },
159
- 'parents': [
160
- {
161
- 'connector': None,
162
- 'metric': None,
163
- 'location': None,
164
- 'instance': None,
165
- },
166
- ],
153
+ 'fetch': {},
167
154
  },
168
155
  }
169
156
  try:
170
157
  conn_type = pipe.connector.type
171
- except Exception as e:
158
+ except Exception:
172
159
  conn_type = None
173
160
  _parameters = _types_defaults.get(conn_type, {})
174
161
 
@@ -210,7 +197,7 @@ def _get_parameters(pipe, debug: bool = False) -> Dict[str, Any]:
210
197
  _parameters['tags'] = [
211
198
  t.strip() for t in prompt(f"Tags for {pipe} (empty to omit):").split(',') if t
212
199
  ]
213
- except Exception as e:
200
+ except Exception:
214
201
  _parameters['tags'] = []
215
202
 
216
203
  return _parameters
@@ -493,6 +493,9 @@ def get_sync_time(
493
493
  from meerschaum.connectors import get_connector_plugin
494
494
  from meerschaum.utils.misc import round_time
495
495
 
496
+ if not self.columns.get('datetime', None):
497
+ return None
498
+
496
499
  with Venv(get_connector_plugin(self.instance_connector)):
497
500
  sync_time = self.instance_connector.get_sync_time(
498
501
  self,
@@ -127,15 +127,15 @@ def prompt(
127
127
 
128
128
 
129
129
  def yes_no(
130
- question: str = '',
131
- options: Tuple[str, str] = ('y', 'n'),
132
- default: str = 'y',
133
- wrappers: Tuple[str, str] = ('[', ']'),
134
- icon: bool = True,
135
- yes: bool = False,
136
- noask: bool = False,
137
- **kw : Any
138
- ) -> bool:
130
+ question: str = '',
131
+ options: Tuple[str, str] = ('y', 'n'),
132
+ default: str = 'y',
133
+ wrappers: Tuple[str, str] = ('[', ']'),
134
+ icon: bool = True,
135
+ yes: bool = False,
136
+ noask: bool = False,
137
+ **kw : Any
138
+ ) -> bool:
139
139
  """
140
140
  Print a question and prompt the user with a yes / no input.
141
141
  Returns `True` for `'yes'`, False for `'no'`.
meerschaum/utils/sql.py CHANGED
@@ -2229,11 +2229,22 @@ def get_reset_autoincrement_queries(
2229
2229
  table_seq_name = sql_item_name(table + '_' + column + '_seq', connector.flavor, schema)
2230
2230
  column_name = sql_item_name(column, connector.flavor)
2231
2231
  if connector.flavor == 'oracle':
2232
- df = connector.read(f"""
2232
+ potential_table_names = set([
2233
+ f"'{table_trunc.upper()}'",
2234
+ f"'{table_trunc}'",
2235
+ f"'{table_name}'",
2236
+ f"'{table_name.upper()}'",
2237
+ ])
2238
+ df = connector.read(
2239
+ """
2233
2240
  SELECT SEQUENCE_NAME
2234
2241
  FROM ALL_TAB_IDENTITY_COLS
2235
- WHERE TABLE_NAME IN '{table_trunc.upper()}'
2236
- """, debug=debug)
2242
+ WHERE TABLE_NAME IN ("""
2243
+ + ", ".join([name for name in potential_table_names])
2244
+ + """)
2245
+ """,
2246
+ debug=debug
2247
+ )
2237
2248
  if len(df) > 0:
2238
2249
  table_seq_name = df['sequence_name'][0]
2239
2250