meerschaum 2.4.0rc2__py3-none-any.whl → 2.4.2__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 +1 -1
- meerschaum/api/dash/callbacks/dashboard.py +7 -0
- meerschaum/api/dash/callbacks/pipes.py +19 -5
- meerschaum/api/dash/pipes.py +17 -2
- meerschaum/config/__init__.py +9 -9
- meerschaum/config/_read_config.py +10 -10
- meerschaum/config/_sync.py +20 -13
- meerschaum/config/_version.py +1 -1
- meerschaum/config/stack/__init__.py +1 -1
- meerschaum/connectors/api/_APIConnector.py +2 -1
- meerschaum/connectors/sql/_create_engine.py +64 -67
- meerschaum/connectors/sql/_pipes.py +8 -5
- meerschaum/core/Pipe/_data.py +16 -7
- meerschaum/core/Pipe/_sync.py +0 -2
- meerschaum/jobs/__init__.py +2 -1
- meerschaum/utils/packages/__init__.py +176 -124
- meerschaum/utils/packages/_packages.py +4 -1
- meerschaum/utils/schedule.py +1 -0
- meerschaum/utils/venv/__init__.py +10 -9
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/METADATA +17 -5
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/RECORD +27 -27
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/WHEEL +1 -1
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/LICENSE +0 -0
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/NOTICE +0 -0
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/top_level.txt +0 -0
- {meerschaum-2.4.0rc2.dist-info → meerschaum-2.4.2.dist-info}/zip-safe +0 -0
meerschaum/actions/bootstrap.py
CHANGED
@@ -336,7 +336,7 @@ def _bootstrap_connectors(
|
|
336
336
|
return abort_tuple
|
337
337
|
new_attributes['flavor'] = flavor
|
338
338
|
required = sorted(list(connector_attributes[_type]['flavors'][flavor]['requirements']))
|
339
|
-
|
339
|
+
optional = sorted(list(connector_attributes[_type]['flavors'][flavor].get('optional', {})))
|
340
340
|
default = type_attributes['flavors'][flavor].get('defaults', {})
|
341
341
|
else:
|
342
342
|
required = sorted(list(type_attributes.get('required', {})))
|
@@ -214,6 +214,13 @@ def update_content(*args):
|
|
214
214
|
trigger = ctx.triggered[0]['prop_id'].split('.')[0] if not trigger else trigger
|
215
215
|
|
216
216
|
session_data = args[-1]
|
217
|
+
mrsm_location_href = session_data.get('mrsm-location.href', None)
|
218
|
+
if (
|
219
|
+
initial_load
|
220
|
+
and mrsm_location_href
|
221
|
+
and not mrsm_location_href.rstrip('/').endswith('/dash')
|
222
|
+
):
|
223
|
+
raise PreventUpdate
|
217
224
|
|
218
225
|
### NOTE: functions MUST return a list of content and a list of alerts
|
219
226
|
triggers = {
|
@@ -5,7 +5,9 @@
|
|
5
5
|
Define callbacks for the `/dash/pipes/` page.
|
6
6
|
"""
|
7
7
|
|
8
|
-
from
|
8
|
+
from urllib.parse import parse_qs
|
9
|
+
|
10
|
+
from dash.dependencies import Input, Output, State
|
9
11
|
from dash import no_update
|
10
12
|
|
11
13
|
import meerschaum as mrsm
|
@@ -13,17 +15,28 @@ from meerschaum.api.dash import dash_app
|
|
13
15
|
from meerschaum.api.dash.pipes import build_pipe_card
|
14
16
|
from meerschaum.api import CHECK_UPDATE
|
15
17
|
from meerschaum.utils.packages import import_html, import_dcc
|
18
|
+
from meerschaum.api.dash.sessions import is_session_authenticated
|
19
|
+
from meerschaum.utils.typing import Optional, Dict, Any
|
16
20
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
17
21
|
|
18
22
|
|
19
23
|
@dash_app.callback(
|
20
24
|
Output('pipe-output-div', 'children'),
|
21
25
|
Input('pipes-location', 'pathname'),
|
26
|
+
State('pipes-location', 'search'),
|
27
|
+
State('session-store', 'data'),
|
22
28
|
)
|
23
|
-
def render_page_from_url(
|
29
|
+
def render_page_from_url(
|
30
|
+
pathname: str,
|
31
|
+
pipe_search: str,
|
32
|
+
session_data: Optional[Dict[str, Any]],
|
33
|
+
):
|
24
34
|
if not str(pathname).startswith('/dash/pipes'):
|
25
35
|
return no_update
|
26
36
|
|
37
|
+
session_id = (session_data or {}).get('session-id', None)
|
38
|
+
authenticated = is_session_authenticated(str(session_id))
|
39
|
+
|
27
40
|
keys = pathname.replace('/dash/pipes', '').lstrip('/').rstrip('/').split('/')
|
28
41
|
if len(keys) not in (2, 3):
|
29
42
|
return no_update
|
@@ -31,11 +44,12 @@ def render_page_from_url(pathname):
|
|
31
44
|
ck = keys[0]
|
32
45
|
mk = keys[1]
|
33
46
|
lk = keys[2] if len(keys) == 3 else None
|
47
|
+
query_params = parse_qs(pipe_search.lstrip('?')) if pipe_search else {}
|
48
|
+
instance = query_params.get('instance', [None])[0]
|
34
49
|
|
35
|
-
pipe = mrsm.Pipe(ck, mk, lk)
|
36
|
-
### TODO Check if logged in
|
50
|
+
pipe = mrsm.Pipe(ck, mk, lk, instance=instance)
|
37
51
|
return [
|
38
52
|
html.Br(),
|
39
|
-
build_pipe_card(pipe, authenticated=False),
|
53
|
+
build_pipe_card(pipe, authenticated=authenticated, include_manage=False),
|
40
54
|
html.Br(),
|
41
55
|
]
|
meerschaum/api/dash/pipes.py
CHANGED
@@ -10,6 +10,8 @@ from __future__ import annotations
|
|
10
10
|
import json
|
11
11
|
import shlex
|
12
12
|
from textwrap import dedent
|
13
|
+
from urllib.parse import urlencode
|
14
|
+
|
13
15
|
from dash.dependencies import Input, Output, State
|
14
16
|
from meerschaum.utils.typing import List, Optional, Dict, Any, Tuple, Union
|
15
17
|
from meerschaum.utils.misc import string_to_dict
|
@@ -30,6 +32,7 @@ html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHEC
|
|
30
32
|
humanfriendly = attempt_import('humanfriendly', check_update=CHECK_UPDATE)
|
31
33
|
pd = import_pandas()
|
32
34
|
|
35
|
+
|
33
36
|
def pipe_from_ctx(ctx, trigger_property: str = 'n_clicks') -> Union[mrsm.Pipe, None]:
|
34
37
|
"""
|
35
38
|
Return a `meerschaum.Pipe` object from a dynamic object with an
|
@@ -105,6 +108,7 @@ def pipes_from_state(
|
|
105
108
|
def build_pipe_card(
|
106
109
|
pipe: mrsm.Pipe,
|
107
110
|
authenticated: bool = False,
|
111
|
+
include_manage: bool = True,
|
108
112
|
_build_children_num: int = 10,
|
109
113
|
) -> 'dbc.Card':
|
110
114
|
"""
|
@@ -118,6 +122,9 @@ def build_pipe_card(
|
|
118
122
|
authenticated: bool, default False
|
119
123
|
If `True`, allow editing functionality to the card.
|
120
124
|
|
125
|
+
include_manage: bool, default True
|
126
|
+
If `True` and `authenticated` is `True`, include the "Manage" dropdown.
|
127
|
+
|
121
128
|
Returns
|
122
129
|
-------
|
123
130
|
A dash bootstrap components Card representation of the pipe.
|
@@ -184,7 +191,7 @@ def build_pipe_card(
|
|
184
191
|
size='sm',
|
185
192
|
color='secondary',
|
186
193
|
)
|
187
|
-
) if authenticated else [],
|
194
|
+
) if authenticated and include_manage else [],
|
188
195
|
width=2,
|
189
196
|
),
|
190
197
|
dbc.Col(width=6),
|
@@ -217,8 +224,16 @@ def build_pipe_card(
|
|
217
224
|
|
218
225
|
]
|
219
226
|
|
227
|
+
query_params = {}
|
228
|
+
default_instance = get_config('meerschaum', 'instance')
|
229
|
+
if pipe.instance_keys != default_instance:
|
230
|
+
query_params['instance'] = pipe.instance_keys
|
220
231
|
pipe_url = (
|
221
|
-
f"/dash/pipes/
|
232
|
+
f"/dash/pipes/"
|
233
|
+
+ f"{pipe.connector_keys}/"
|
234
|
+
+ f"{pipe.metric_key}/"
|
235
|
+
+ (f"{pipe.location_key}" if pipe.location_key is not None else '')
|
236
|
+
+ (f"?{urlencode(query_params)}" if query_params else "")
|
222
237
|
)
|
223
238
|
|
224
239
|
card_header_children = dbc.Row(
|
meerschaum/config/__init__.py
CHANGED
@@ -79,15 +79,15 @@ def set_config(cf: Dict[str, Any]) -> Dict[str, Any]:
|
|
79
79
|
|
80
80
|
|
81
81
|
def get_config(
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
82
|
+
*keys: str,
|
83
|
+
patch: bool = True,
|
84
|
+
substitute: bool = True,
|
85
|
+
sync_files: bool = True,
|
86
|
+
write_missing: bool = True,
|
87
|
+
as_tuple: bool = False,
|
88
|
+
warn: bool = True,
|
89
|
+
debug: bool = False
|
90
|
+
) -> Any:
|
91
91
|
"""
|
92
92
|
Return the Meerschaum configuration dictionary.
|
93
93
|
If positional arguments are provided, index by the keys.
|
@@ -10,12 +10,12 @@ from meerschaum.utils.typing import Optional, Dict, Any, List, Tuple, Union
|
|
10
10
|
from meerschaum.config import get_config
|
11
11
|
|
12
12
|
def read_config(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
directory: Optional[str] = None,
|
14
|
+
keys: Optional[List[str]] = None,
|
15
|
+
write_missing : bool = True,
|
16
|
+
substitute : bool = True,
|
17
|
+
with_filenames : bool = False,
|
18
|
+
) -> Union[Dict[str, Any], Tuple[Dict[str, Any], List[str]]]:
|
19
19
|
"""
|
20
20
|
Read the configuration directory.
|
21
21
|
|
@@ -313,10 +313,10 @@ def search_and_substitute_config(
|
|
313
313
|
try:
|
314
314
|
valid, value = get_config(
|
315
315
|
*keys,
|
316
|
-
substitute
|
317
|
-
as_tuple
|
318
|
-
write_missing
|
319
|
-
sync_files
|
316
|
+
substitute=False,
|
317
|
+
as_tuple=True,
|
318
|
+
write_missing=False,
|
319
|
+
sync_files=False,
|
320
320
|
)
|
321
321
|
except Exception as e:
|
322
322
|
import traceback
|
meerschaum/config/_sync.py
CHANGED
@@ -7,17 +7,20 @@ Synchronize across config files
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
+
import pathlib
|
10
11
|
from meerschaum.utils.typing import Optional, List, Tuple
|
11
12
|
|
13
|
+
|
12
14
|
def sync_yaml_configs(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
"""
|
20
|
-
|
15
|
+
keys: List[str],
|
16
|
+
sub_path: pathlib.Path,
|
17
|
+
substitute: bool = True,
|
18
|
+
permissions: Optional[int] = None,
|
19
|
+
replace_tuples: Optional[List[Tuple[str, str]]] = None,
|
20
|
+
) -> None:
|
21
|
+
"""
|
22
|
+
Synchronize sub-configuration with main configuration file.
|
23
|
+
|
21
24
|
Parameters
|
22
25
|
----------
|
23
26
|
keys: List[str]
|
@@ -84,12 +87,14 @@ def sync_yaml_configs(
|
|
84
87
|
new_path = sub_path
|
85
88
|
|
86
89
|
### write changes
|
90
|
+
new_path.parent.mkdir(exist_ok=True, parents=True)
|
87
91
|
with open(new_path, 'w+', encoding='utf-8') as f:
|
88
92
|
f.write(new_header)
|
89
93
|
f.write(new_config_text)
|
90
94
|
if permissions is not None:
|
91
95
|
os.chmod(new_path, permissions)
|
92
96
|
|
97
|
+
|
93
98
|
def sync_files(keys: Optional[List[str]] = None):
|
94
99
|
if keys is None:
|
95
100
|
keys = []
|
@@ -110,21 +115,23 @@ def sync_files(keys: Optional[List[str]] = None):
|
|
110
115
|
sync_yaml_configs(
|
111
116
|
['stack', STACK_COMPOSE_FILENAME],
|
112
117
|
STACK_COMPOSE_PATH,
|
113
|
-
substitute
|
114
|
-
replace_tuples
|
118
|
+
substitute=True,
|
119
|
+
replace_tuples=[
|
120
|
+
('$', '$$'),
|
121
|
+
('<DOLLAR>', '$'),
|
122
|
+
],
|
115
123
|
)
|
116
124
|
sync_yaml_configs(
|
117
125
|
['stack', 'grafana', 'datasource'],
|
118
126
|
GRAFANA_DATASOURCE_PATH,
|
119
|
-
substitute
|
127
|
+
substitute=True,
|
120
128
|
)
|
121
129
|
sync_yaml_configs(
|
122
130
|
['stack', 'grafana', 'dashboard'],
|
123
131
|
GRAFANA_DASHBOARD_PATH,
|
124
|
-
substitute
|
132
|
+
substitute=True,
|
125
133
|
)
|
126
134
|
|
127
|
-
|
128
135
|
key_functions = {
|
129
136
|
'stack': _stack,
|
130
137
|
}
|
meerschaum/config/_version.py
CHANGED
@@ -168,7 +168,8 @@ class APIConnector(Connector):
|
|
168
168
|
@property
|
169
169
|
def session(self):
|
170
170
|
if self._session is None:
|
171
|
-
|
171
|
+
certifi = attempt_import('certifi', lazy=False)
|
172
|
+
requests = attempt_import('requests', lazy=False)
|
172
173
|
if requests:
|
173
174
|
self._session = requests.Session()
|
174
175
|
if self._session is None:
|
@@ -27,39 +27,39 @@ default_create_engine_args = {
|
|
27
27
|
'connect_args': {},
|
28
28
|
}
|
29
29
|
flavor_configs = {
|
30
|
-
'timescaledb'
|
31
|
-
'engine'
|
32
|
-
'create_engine'
|
30
|
+
'timescaledb': {
|
31
|
+
'engine': 'postgresql+psycopg',
|
32
|
+
'create_engine': default_create_engine_args,
|
33
33
|
'omit_create_engine': {'method',},
|
34
|
-
'to_sql'
|
35
|
-
'requirements'
|
36
|
-
'defaults'
|
37
|
-
'port'
|
34
|
+
'to_sql': {},
|
35
|
+
'requirements': default_requirements,
|
36
|
+
'defaults': {
|
37
|
+
'port': 5432,
|
38
38
|
},
|
39
39
|
},
|
40
|
-
'postgresql'
|
41
|
-
'engine'
|
42
|
-
'create_engine'
|
40
|
+
'postgresql': {
|
41
|
+
'engine': 'postgresql+psycopg',
|
42
|
+
'create_engine': default_create_engine_args,
|
43
43
|
'omit_create_engine': {'method',},
|
44
|
-
'to_sql'
|
45
|
-
'requirements'
|
46
|
-
'defaults'
|
47
|
-
'port'
|
44
|
+
'to_sql': {},
|
45
|
+
'requirements': default_requirements,
|
46
|
+
'defaults': {
|
47
|
+
'port': 5432,
|
48
48
|
},
|
49
49
|
},
|
50
|
-
'citus'
|
51
|
-
'engine'
|
52
|
-
'create_engine'
|
50
|
+
'citus': {
|
51
|
+
'engine': 'postgresql+psycopg',
|
52
|
+
'create_engine': default_create_engine_args,
|
53
53
|
'omit_create_engine': {'method',},
|
54
|
-
'to_sql'
|
55
|
-
'requirements'
|
56
|
-
'defaults'
|
57
|
-
'port'
|
54
|
+
'to_sql': {},
|
55
|
+
'requirements': default_requirements,
|
56
|
+
'defaults': {
|
57
|
+
'port': 5432,
|
58
58
|
},
|
59
59
|
},
|
60
|
-
'mssql'
|
61
|
-
'engine'
|
62
|
-
'create_engine'
|
60
|
+
'mssql': {
|
61
|
+
'engine': 'mssql+pyodbc',
|
62
|
+
'create_engine': {
|
63
63
|
'fast_executemany': True,
|
64
64
|
'isolation_level': 'AUTOCOMMIT',
|
65
65
|
'use_setinputsizes': False,
|
@@ -68,84 +68,81 @@ flavor_configs = {
|
|
68
68
|
'to_sql': {
|
69
69
|
'method': None,
|
70
70
|
},
|
71
|
-
'requirements'
|
72
|
-
'defaults'
|
73
|
-
'port'
|
74
|
-
'options'
|
75
|
-
'driver' : 'ODBC Driver 17 for SQL Server',
|
76
|
-
'UseFMTONLY': 'Yes',
|
77
|
-
},
|
71
|
+
'requirements': default_requirements,
|
72
|
+
'defaults': {
|
73
|
+
'port': 1433,
|
74
|
+
'options': "driver=ODBC Driver 17 for SQL Server&UseFMTONLY=Yes",
|
78
75
|
},
|
79
76
|
},
|
80
|
-
'mysql'
|
81
|
-
'engine'
|
82
|
-
'create_engine'
|
77
|
+
'mysql': {
|
78
|
+
'engine': 'mysql+pymysql',
|
79
|
+
'create_engine': default_create_engine_args,
|
83
80
|
'omit_create_engine': {'method',},
|
84
81
|
'to_sql': {
|
85
82
|
'method': 'multi',
|
86
83
|
},
|
87
|
-
'requirements'
|
88
|
-
'defaults'
|
89
|
-
'port'
|
84
|
+
'requirements': default_requirements,
|
85
|
+
'defaults': {
|
86
|
+
'port': 3306,
|
90
87
|
},
|
91
88
|
},
|
92
|
-
'mariadb'
|
93
|
-
'engine'
|
94
|
-
'create_engine'
|
89
|
+
'mariadb': {
|
90
|
+
'engine': 'mysql+pymysql',
|
91
|
+
'create_engine': default_create_engine_args,
|
95
92
|
'omit_create_engine': {'method',},
|
96
93
|
'to_sql': {
|
97
94
|
'method': 'multi',
|
98
95
|
},
|
99
|
-
'requirements'
|
100
|
-
'defaults'
|
101
|
-
'port'
|
96
|
+
'requirements': default_requirements,
|
97
|
+
'defaults': {
|
98
|
+
'port': 3306,
|
102
99
|
},
|
103
100
|
},
|
104
|
-
'oracle'
|
105
|
-
'engine'
|
106
|
-
'create_engine'
|
101
|
+
'oracle': {
|
102
|
+
'engine': 'oracle+cx_oracle',
|
103
|
+
'create_engine': default_create_engine_args,
|
107
104
|
'omit_create_engine': {'method',},
|
108
105
|
'to_sql': {
|
109
106
|
'method': None,
|
110
107
|
},
|
111
|
-
'requirements'
|
112
|
-
'defaults'
|
113
|
-
'port'
|
108
|
+
'requirements': default_requirements,
|
109
|
+
'defaults': {
|
110
|
+
'port': 1521,
|
114
111
|
},
|
115
112
|
},
|
116
|
-
'sqlite'
|
117
|
-
'engine'
|
118
|
-
'create_engine'
|
113
|
+
'sqlite': {
|
114
|
+
'engine': 'sqlite',
|
115
|
+
'create_engine': default_create_engine_args,
|
119
116
|
'omit_create_engine': {'method',},
|
120
117
|
'to_sql': {
|
121
118
|
'method': 'multi',
|
122
119
|
},
|
123
|
-
'requirements'
|
124
|
-
'defaults'
|
120
|
+
'requirements': {'database'},
|
121
|
+
'defaults': {},
|
125
122
|
},
|
126
|
-
'duckdb'
|
127
|
-
'engine'
|
128
|
-
'create_engine'
|
123
|
+
'duckdb': {
|
124
|
+
'engine': 'duckdb',
|
125
|
+
'create_engine': {},
|
129
126
|
'omit_create_engine': {'ALL',},
|
130
127
|
'to_sql': {
|
131
128
|
'method': 'multi',
|
132
129
|
},
|
133
|
-
'requirements'
|
134
|
-
'defaults'
|
130
|
+
'requirements': '',
|
131
|
+
'defaults': {},
|
135
132
|
},
|
136
|
-
'cockroachdb'
|
137
|
-
'engine'
|
133
|
+
'cockroachdb': {
|
134
|
+
'engine': 'cockroachdb',
|
138
135
|
'omit_create_engine': {'method',},
|
139
136
|
'create_engine': default_create_engine_args,
|
140
137
|
'to_sql': {
|
141
138
|
'method': 'multi',
|
142
139
|
},
|
143
|
-
'requirements'
|
144
|
-
'defaults'
|
145
|
-
'port'
|
146
|
-
'database'
|
147
|
-
'username'
|
148
|
-
'password'
|
140
|
+
'requirements': {'host'},
|
141
|
+
'defaults': {
|
142
|
+
'port': 26257,
|
143
|
+
'database': 'defaultdb',
|
144
|
+
'username': 'root',
|
145
|
+
'password': 'admin',
|
149
146
|
},
|
150
147
|
},
|
151
148
|
}
|
@@ -909,7 +909,7 @@ def get_pipe_data_query(
|
|
909
909
|
|
910
910
|
cols_names = [sql_item_name(col, self.flavor, None) for col in select_columns]
|
911
911
|
select_cols_str = (
|
912
|
-
'SELECT\n'
|
912
|
+
'SELECT\n '
|
913
913
|
+ ',\n '.join(
|
914
914
|
[
|
915
915
|
(
|
@@ -953,14 +953,14 @@ def get_pipe_data_query(
|
|
953
953
|
warn(
|
954
954
|
f"No datetime could be determined for {pipe}."
|
955
955
|
+ "\n Ignoring begin and end...",
|
956
|
-
stack
|
956
|
+
stack=False,
|
957
957
|
)
|
958
958
|
begin, end = None, None
|
959
959
|
else:
|
960
960
|
warn(
|
961
961
|
f"A datetime wasn't specified for {pipe}.\n"
|
962
962
|
+ f" Using column \"{_dt}\" for datetime bounds...",
|
963
|
-
stack
|
963
|
+
stack=False,
|
964
964
|
)
|
965
965
|
|
966
966
|
is_dt_bound = False
|
@@ -1014,9 +1014,12 @@ def get_pipe_data_query(
|
|
1014
1014
|
|
1015
1015
|
if isinstance(limit, int):
|
1016
1016
|
if self.flavor == 'mssql':
|
1017
|
-
query = f'SELECT TOP {limit}
|
1017
|
+
query = f'SELECT TOP {limit}\n' + query[len("SELECT "):]
|
1018
1018
|
elif self.flavor == 'oracle':
|
1019
|
-
query =
|
1019
|
+
query = (
|
1020
|
+
f"SELECT * FROM (\n {query}\n)\n"
|
1021
|
+
+ f"WHERE ROWNUM IN ({', '.join([str(i) for i in range(1, limit+1)])})"
|
1022
|
+
)
|
1020
1023
|
else:
|
1021
1024
|
query += f"\nLIMIT {limit}"
|
1022
1025
|
|
meerschaum/core/Pipe/_data.py
CHANGED
@@ -106,7 +106,7 @@ def get_data(
|
|
106
106
|
from meerschaum.connectors import get_connector_plugin
|
107
107
|
from meerschaum.utils.misc import iterate_chunks, items_str
|
108
108
|
from meerschaum.utils.dtypes import to_pandas_dtype
|
109
|
-
from meerschaum.utils.dataframe import add_missing_cols_to_df
|
109
|
+
from meerschaum.utils.dataframe import add_missing_cols_to_df, df_is_chunk_generator
|
110
110
|
from meerschaum.utils.packages import attempt_import
|
111
111
|
dd = attempt_import('dask.dataframe') if as_dask else None
|
112
112
|
dask = attempt_import('dask') if as_dask else None
|
@@ -122,6 +122,8 @@ def get_data(
|
|
122
122
|
as_iterator = as_iterator or as_chunks
|
123
123
|
|
124
124
|
def _sort_df(_df):
|
125
|
+
if df_is_chunk_generator(_df):
|
126
|
+
return _df
|
125
127
|
dt_col = self.columns.get('datetime', None)
|
126
128
|
indices = [] if dt_col not in _df.columns else [dt_col]
|
127
129
|
non_dt_cols = [
|
@@ -130,12 +132,19 @@ def get_data(
|
|
130
132
|
if col_ix != 'datetime' and col in _df.columns
|
131
133
|
]
|
132
134
|
indices.extend(non_dt_cols)
|
133
|
-
_df.
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
135
|
+
if 'dask' not in _df.__module__:
|
136
|
+
_df.sort_values(
|
137
|
+
by=indices,
|
138
|
+
inplace=True,
|
139
|
+
ascending=(str(order).lower() == 'asc'),
|
140
|
+
)
|
141
|
+
_df.reset_index(drop=True, inplace=True)
|
142
|
+
else:
|
143
|
+
_df = _df.sort_values(
|
144
|
+
by=indices,
|
145
|
+
ascending=(str(order).lower() == 'asc'),
|
146
|
+
)
|
147
|
+
_df = _df.reset_index(drop=True)
|
139
148
|
if limit is not None and len(_df) > limit:
|
140
149
|
return _df.head(limit)
|
141
150
|
return _df
|
meerschaum/core/Pipe/_sync.py
CHANGED
meerschaum/jobs/__init__.py
CHANGED
@@ -11,11 +11,12 @@ import pathlib
|
|
11
11
|
import meerschaum as mrsm
|
12
12
|
from meerschaum.utils.typing import Dict, Optional, List, SuccessTuple
|
13
13
|
|
14
|
-
from meerschaum.jobs._Job import Job
|
14
|
+
from meerschaum.jobs._Job import Job, StopMonitoringLogs
|
15
15
|
from meerschaum.jobs._Executor import Executor
|
16
16
|
|
17
17
|
__all__ = (
|
18
18
|
'Job',
|
19
|
+
'StopMonitoringLogs',
|
19
20
|
'systemd',
|
20
21
|
'get_jobs',
|
21
22
|
'get_filtered_jobs',
|