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.
- meerschaum/actions/bootstrap.py +8 -9
- meerschaum/actions/copy.py +4 -3
- meerschaum/config/_default.py +0 -1
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/sql/_fetch.py +3 -3
- meerschaum/connectors/sql/_pipes.py +16 -25
- meerschaum/core/Pipe/_attributes.py +21 -11
- meerschaum/core/Pipe/_bootstrap.py +24 -37
- meerschaum/core/Pipe/_sync.py +3 -0
- meerschaum/utils/prompt.py +9 -9
- meerschaum/utils/sql.py +14 -3
- meerschaum-2.6.16.dist-info/METADATA +517 -0
- {meerschaum-2.6.14.dist-info → meerschaum-2.6.16.dist-info}/RECORD +19 -19
- {meerschaum-2.6.14.dist-info → meerschaum-2.6.16.dist-info}/WHEEL +1 -1
- meerschaum-2.6.14.dist-info/METADATA +0 -517
- {meerschaum-2.6.14.dist-info → meerschaum-2.6.16.dist-info}/LICENSE +0 -0
- {meerschaum-2.6.14.dist-info → meerschaum-2.6.16.dist-info}/NOTICE +0 -0
- {meerschaum-2.6.14.dist-info → meerschaum-2.6.16.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.6.14.dist-info → meerschaum-2.6.16.dist-info}/top_level.txt +0 -0
- {meerschaum-2.6.14.dist-info → meerschaum-2.6.16.dist-info}/zip-safe +0 -0
meerschaum/actions/bootstrap.py
CHANGED
@@ -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
|
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
|
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
|
-
|
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(
|
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
|
-
|
146
|
-
|
147
|
-
|
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,
|
meerschaum/actions/copy.py
CHANGED
@@ -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
|
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,
|
112
|
+
noask=noask,
|
113
|
+
yes=yes,
|
114
|
+
default='n',
|
114
115
|
)
|
115
116
|
):
|
116
117
|
_new_pipe.sync(
|
meerschaum/config/_default.py
CHANGED
meerschaum/config/_version.py
CHANGED
@@ -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
|
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
|
292
|
+
elif 'definition' in pipe.parameters:
|
293
293
|
dict_to_set = pipe.parameters
|
294
294
|
key_to_set = 'definition'
|
295
|
-
elif
|
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:
|
1774
|
-
end:
|
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:
|
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:
|
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
|
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
|
-
|
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
|
2377
|
-
valid_params[
|
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 {
|
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 {
|
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 {
|
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
|
-
|
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
|
-
|
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(
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
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,
|
10
|
+
from meerschaum.utils.typing import SuccessTuple, Dict, Any
|
11
|
+
|
11
12
|
|
12
13
|
def bootstrap(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
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
|
78
|
-
return False, f"
|
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
|
-
|
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
|
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
|
-
'
|
145
|
-
|
146
|
-
|
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
|
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
|
200
|
+
except Exception:
|
214
201
|
_parameters['tags'] = []
|
215
202
|
|
216
203
|
return _parameters
|
meerschaum/core/Pipe/_sync.py
CHANGED
@@ -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,
|
meerschaum/utils/prompt.py
CHANGED
@@ -127,15 +127,15 @@ def prompt(
|
|
127
127
|
|
128
128
|
|
129
129
|
def yes_no(
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
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
|
2236
|
-
|
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
|
|