meerschaum 2.4.10__py3-none-any.whl → 2.4.12__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/_internal/arguments/_parse_arguments.py +15 -1
- meerschaum/_internal/docs/index.py +1 -0
- meerschaum/_internal/shell/Shell.py +19 -9
- meerschaum/_internal/shell/ShellCompleter.py +11 -6
- meerschaum/actions/bootstrap.py +120 -15
- meerschaum/actions/clear.py +41 -30
- meerschaum/actions/edit.py +89 -0
- meerschaum/actions/start.py +3 -2
- meerschaum/actions/sync.py +3 -2
- meerschaum/api/dash/callbacks/dashboard.py +2 -1
- meerschaum/api/dash/callbacks/jobs.py +53 -7
- meerschaum/api/dash/callbacks/pipes.py +1 -1
- meerschaum/api/dash/jobs.py +86 -60
- meerschaum/api/dash/pages/__init__.py +1 -0
- meerschaum/api/dash/pages/job.py +21 -0
- meerschaum/api/routes/_jobs.py +3 -3
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/sql/_fetch.py +65 -61
- meerschaum/connectors/sql/_pipes.py +36 -29
- meerschaum/core/Pipe/_data.py +1 -1
- meerschaum/utils/formatting/__init__.py +32 -16
- meerschaum/utils/formatting/_pipes.py +1 -1
- meerschaum/utils/formatting/_shell.py +4 -3
- meerschaum/utils/prompt.py +16 -15
- meerschaum/utils/sql.py +107 -35
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/METADATA +1 -1
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/RECORD +33 -32
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/WHEEL +1 -1
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/LICENSE +0 -0
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/NOTICE +0 -0
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/top_level.txt +0 -0
- {meerschaum-2.4.10.dist-info → meerschaum-2.4.12.dist-info}/zip-safe +0 -0
@@ -12,6 +12,7 @@ import json
|
|
12
12
|
import time
|
13
13
|
import traceback
|
14
14
|
from datetime import datetime, timezone
|
15
|
+
|
15
16
|
from meerschaum.utils.typing import Optional, Dict, Any
|
16
17
|
from meerschaum.api import CHECK_UPDATE
|
17
18
|
from meerschaum.api.dash import dash_app
|
@@ -19,17 +20,19 @@ from meerschaum.api.dash.sessions import get_username_from_session
|
|
19
20
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html
|
20
21
|
from meerschaum.api.dash.components import alert_from_success_tuple
|
21
22
|
from meerschaum.api.dash.jobs import (
|
23
|
+
build_job_card,
|
22
24
|
build_manage_job_buttons_div_children,
|
23
25
|
build_status_children,
|
24
26
|
build_process_timestamps_children,
|
25
27
|
)
|
26
|
-
from meerschaum.
|
28
|
+
from meerschaum.api.routes._jobs import _get_job
|
27
29
|
from meerschaum.api.dash.sessions import is_session_authenticated
|
28
30
|
dash = attempt_import('dash', lazy=False, check_update=CHECK_UPDATE)
|
29
31
|
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
30
32
|
from dash.exceptions import PreventUpdate
|
31
33
|
from dash.dependencies import Input, Output, State, ALL, MATCH
|
32
34
|
import dash_bootstrap_components as dbc
|
35
|
+
from dash import no_update
|
33
36
|
|
34
37
|
|
35
38
|
@dash_app.callback(
|
@@ -53,6 +56,13 @@ def download_job_logs(n_clicks):
|
|
53
56
|
|
54
57
|
component_dict = json.loads(ctx[0]['prop_id'].split('.' + 'n_clicks')[0])
|
55
58
|
job_name = component_dict['index']
|
59
|
+
try:
|
60
|
+
job = _get_job(job_name)
|
61
|
+
except Exception:
|
62
|
+
job = None
|
63
|
+
if job is None or not job.exists():
|
64
|
+
raise PreventUpdate
|
65
|
+
|
56
66
|
now = datetime.now(timezone.utc)
|
57
67
|
filename = job_name + '_' + str(int(now.timestamp())) + '.log'
|
58
68
|
return {
|
@@ -69,7 +79,7 @@ def download_job_logs(n_clicks):
|
|
69
79
|
Input({'type': 'manage-job-button', 'action': ALL, 'index': MATCH}, 'n_clicks'),
|
70
80
|
State('session-store', 'data'),
|
71
81
|
State({'type': 'job-label-p', 'index': MATCH}, 'children'),
|
72
|
-
prevent_initial_call
|
82
|
+
prevent_initial_call=True,
|
73
83
|
)
|
74
84
|
def manage_job_button_click(
|
75
85
|
n_clicks: Optional[int] = None,
|
@@ -102,10 +112,10 @@ def manage_job_button_click(
|
|
102
112
|
job_name = component_dict['index']
|
103
113
|
manage_job_action = component_dict['action']
|
104
114
|
try:
|
105
|
-
job =
|
106
|
-
except Exception
|
115
|
+
job = _get_job(job_name, job_label.replace('\n', ' ') if job_label else None)
|
116
|
+
except Exception:
|
107
117
|
job = None
|
108
|
-
if job is None:
|
118
|
+
if job is None or not job.exists():
|
109
119
|
raise PreventUpdate
|
110
120
|
|
111
121
|
manage_functions = {
|
@@ -191,7 +201,7 @@ dash_app.clientside_callback(
|
|
191
201
|
Output({'type': 'process-timestamps-div', 'index': ALL}, 'children'),
|
192
202
|
Input('refresh-jobs-interval', 'n_intervals'),
|
193
203
|
State('session-store', 'data'),
|
194
|
-
prevent_initial_call
|
204
|
+
prevent_initial_call=True,
|
195
205
|
)
|
196
206
|
def refresh_jobs_on_interval(
|
197
207
|
n_intervals: Optional[int] = None,
|
@@ -209,7 +219,7 @@ def refresh_jobs_on_interval(
|
|
209
219
|
]
|
210
220
|
|
211
221
|
### NOTE: The job may have been deleted, but the card may still exist.
|
212
|
-
jobs = [
|
222
|
+
jobs = [_get_job(name) for name in job_names]
|
213
223
|
|
214
224
|
return (
|
215
225
|
[
|
@@ -229,3 +239,39 @@ def refresh_jobs_on_interval(
|
|
229
239
|
for job in jobs
|
230
240
|
],
|
231
241
|
)
|
242
|
+
|
243
|
+
|
244
|
+
@dash_app.callback(
|
245
|
+
Output('job-output-div', 'children'),
|
246
|
+
Input('job-location', 'pathname'),
|
247
|
+
State('session-store', 'data'),
|
248
|
+
)
|
249
|
+
def render_job_page_from_url(
|
250
|
+
pathname: str,
|
251
|
+
session_data: Optional[Dict[str, Any]],
|
252
|
+
):
|
253
|
+
"""
|
254
|
+
Load the `/job/{name}` page.
|
255
|
+
"""
|
256
|
+
if not str(pathname).startswith('/dash/job'):
|
257
|
+
return no_update
|
258
|
+
|
259
|
+
session_id = (session_data or {}).get('session-id', None)
|
260
|
+
authenticated = is_session_authenticated(str(session_id))
|
261
|
+
|
262
|
+
job_name = pathname.replace('/dash/job', '').lstrip('/').rstrip('/')
|
263
|
+
if not job_name:
|
264
|
+
return no_update
|
265
|
+
|
266
|
+
job = _get_job(job_name)
|
267
|
+
if not job.exists():
|
268
|
+
return [
|
269
|
+
html.Br(),
|
270
|
+
html.H2("404: Job does not exist."),
|
271
|
+
]
|
272
|
+
|
273
|
+
return [
|
274
|
+
html.Br(),
|
275
|
+
build_job_card(job, authenticated=authenticated, include_follow=False),
|
276
|
+
html.Br(),
|
277
|
+
]
|
@@ -26,7 +26,7 @@ html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHEC
|
|
26
26
|
State('pipes-location', 'search'),
|
27
27
|
State('session-store', 'data'),
|
28
28
|
)
|
29
|
-
def
|
29
|
+
def render_pipe_page_from_url(
|
30
30
|
pathname: str,
|
31
31
|
pipe_search: str,
|
32
32
|
session_data: Optional[Dict[str, Any]],
|
meerschaum/api/dash/jobs.py
CHANGED
@@ -31,6 +31,7 @@ STATUS_EMOJI: Dict[str, str] = {
|
|
31
31
|
|
32
32
|
EXECUTOR_KEYS: str = get_executor_keys_from_context()
|
33
33
|
|
34
|
+
|
34
35
|
def get_jobs_cards(state: WebState):
|
35
36
|
"""
|
36
37
|
Build cards and alerts lists for jobs.
|
@@ -42,71 +43,96 @@ def get_jobs_cards(state: WebState):
|
|
42
43
|
cards = []
|
43
44
|
|
44
45
|
for name, job in jobs.items():
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
46
|
+
cards.append(build_job_card(job, authenticated=is_authenticated))
|
47
|
+
|
48
|
+
return cards, []
|
49
|
+
|
50
|
+
|
51
|
+
def build_job_card(
|
52
|
+
job: Job,
|
53
|
+
authenticated: bool = False,
|
54
|
+
include_follow: bool = True,
|
55
|
+
):
|
56
|
+
"""
|
57
|
+
Return a card for a given job.
|
58
|
+
"""
|
59
|
+
footer_children = html.Div(
|
60
|
+
build_process_timestamps_children(job),
|
61
|
+
id={'type': 'process-timestamps-div', 'index': job.name},
|
62
|
+
)
|
63
|
+
follow_logs_button = dbc.DropdownMenuItem(
|
64
|
+
"Follow logs",
|
65
|
+
id={'type': 'follow-logs-button', 'index': job.name},
|
66
|
+
)
|
67
|
+
download_logs_button = dbc.DropdownMenuItem(
|
68
|
+
"Download logs",
|
69
|
+
id={'type': 'job-download-logs-button', 'index': job.name},
|
70
|
+
)
|
71
|
+
logs_menu_children = (
|
72
|
+
([follow_logs_button] if include_follow else []) + [download_logs_button]
|
73
|
+
if authenticated
|
74
|
+
else []
|
75
|
+
)
|
76
|
+
header_children = [
|
77
|
+
html.Div(
|
78
|
+
build_status_children(job),
|
79
|
+
id={'type': 'manage-job-status-div', 'index': job.name},
|
80
|
+
style={'float': 'left'},
|
81
|
+
),
|
82
|
+
] + ([
|
83
|
+
html.Div(
|
84
|
+
dbc.DropdownMenu(
|
85
|
+
logs_menu_children,
|
86
|
+
label="Logs",
|
87
|
+
size="sm",
|
88
|
+
align_end=True,
|
89
|
+
color="secondary",
|
90
|
+
menu_variant='dark',
|
65
91
|
),
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
92
|
+
style={'float': 'right'},
|
93
|
+
),
|
94
|
+
] if authenticated else [])
|
95
|
+
|
96
|
+
body_children = [
|
97
|
+
html.H4(
|
98
|
+
html.B(
|
99
|
+
html.A(
|
100
|
+
"🔗 " + job.name,
|
101
|
+
href=f"/dash/job/{job.name}",
|
102
|
+
target="_blank",
|
103
|
+
style={
|
104
|
+
'color': 'white',
|
105
|
+
'text-decoration': 'none',
|
106
|
+
},
|
107
|
+
)
|
76
108
|
),
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
html.
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
style={"word-wrap": "break-word"},
|
86
|
-
id={'type': 'job-label-p', 'index': name},
|
87
|
-
),
|
88
|
-
style={"white-space": "pre-wrap"},
|
109
|
+
className="card-title",
|
110
|
+
),
|
111
|
+
html.Div(
|
112
|
+
html.P(
|
113
|
+
job.label,
|
114
|
+
className="card-text job-card-text",
|
115
|
+
style={"word-wrap": "break-word"},
|
116
|
+
id={'type': 'job-label-p', 'index': job.name},
|
89
117
|
),
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
118
|
+
style={"white-space": "pre-wrap"},
|
119
|
+
),
|
120
|
+
html.Div(
|
121
|
+
(
|
122
|
+
build_manage_job_buttons_div_children(job)
|
123
|
+
if authenticated
|
124
|
+
else []
|
97
125
|
),
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
dbc.Card([
|
103
|
-
dbc.CardHeader(header_children),
|
104
|
-
dbc.CardBody(body_children),
|
105
|
-
dbc.CardFooter(footer_children),
|
106
|
-
])
|
107
|
-
)
|
126
|
+
id={'type': 'manage-job-buttons-div', 'index': job.name},
|
127
|
+
),
|
128
|
+
html.Div(id={'type': 'manage-job-alert-div', 'index': job.name}),
|
129
|
+
]
|
108
130
|
|
109
|
-
return
|
131
|
+
return dbc.Card([
|
132
|
+
dbc.CardHeader(header_children),
|
133
|
+
dbc.CardBody(body_children),
|
134
|
+
dbc.CardFooter(footer_children),
|
135
|
+
])
|
110
136
|
|
111
137
|
|
112
138
|
def build_manage_job_buttons_div_children(job: Job):
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#! /usr/bin/env python3
|
2
|
+
# vim:fenc=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
Display pipes via a shareable URL.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from meerschaum.api import CHECK_UPDATE
|
9
|
+
from meerschaum.utils.packages import import_html, import_dcc
|
10
|
+
|
11
|
+
html, dcc = import_html(check_update=CHECK_UPDATE), import_dcc(check_update=CHECK_UPDATE)
|
12
|
+
import dash_bootstrap_components as dbc
|
13
|
+
|
14
|
+
from meerschaum.api.dash.components import download_logs, refresh_jobs_interval
|
15
|
+
|
16
|
+
layout = dbc.Container([
|
17
|
+
dcc.Location('job-location'),
|
18
|
+
html.Div(id='job-output-div'),
|
19
|
+
download_logs,
|
20
|
+
refresh_jobs_interval,
|
21
|
+
])
|
meerschaum/api/routes/_jobs.py
CHANGED
@@ -39,12 +39,12 @@ NONINTERACTIVE_ENV: str = STATIC_CONFIG['environment']['noninteractive']
|
|
39
39
|
EXECUTOR_KEYS: str = 'local'
|
40
40
|
|
41
41
|
|
42
|
-
def _get_job(name: str):
|
43
|
-
systemd_job = Job(name, executor_keys='systemd')
|
42
|
+
def _get_job(name: str, sysargs: Union[str, List[str], None] = None):
|
43
|
+
systemd_job = Job(name, sysargs, executor_keys='systemd')
|
44
44
|
if systemd_job.exists():
|
45
45
|
return systemd_job
|
46
46
|
|
47
|
-
job = Job(name, executor_keys=EXECUTOR_KEYS)
|
47
|
+
job = Job(name, sysargs, executor_keys=EXECUTOR_KEYS)
|
48
48
|
return job
|
49
49
|
|
50
50
|
|
meerschaum/config/_version.py
CHANGED
@@ -7,27 +7,29 @@ Implement the Connector fetch() method
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
+
|
10
11
|
from datetime import datetime, timedelta
|
11
12
|
import meerschaum as mrsm
|
12
|
-
from meerschaum.utils.typing import Optional, Union, Callable, Any
|
13
|
+
from meerschaum.utils.typing import Optional, Union, Callable, Any, List, Dict
|
14
|
+
|
13
15
|
|
14
16
|
def fetch(
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
self,
|
18
|
+
pipe: mrsm.Pipe,
|
19
|
+
begin: Union[datetime, int, str, None] = '',
|
20
|
+
end: Union[datetime, int, str, None] = None,
|
21
|
+
check_existing: bool = True,
|
22
|
+
chunk_hook: Optional[Callable[['pd.DataFrame'], Any]] = None,
|
23
|
+
chunksize: Optional[int] = -1,
|
24
|
+
workers: Optional[int] = None,
|
25
|
+
debug: bool = False,
|
26
|
+
**kw: Any
|
27
|
+
) -> Union['pd.DataFrame', List[Any], None]:
|
26
28
|
"""Execute the SQL definition and return a Pandas DataFrame.
|
27
29
|
|
28
30
|
Parameters
|
29
31
|
----------
|
30
|
-
pipe:
|
32
|
+
pipe: mrsm.Pipe
|
31
33
|
The pipe object which contains the `fetch` metadata.
|
32
34
|
|
33
35
|
- pipe.columns['datetime']: str
|
@@ -63,7 +65,7 @@ def fetch(
|
|
63
65
|
|
64
66
|
debug: bool, default False
|
65
67
|
Verbosity toggle.
|
66
|
-
|
68
|
+
|
67
69
|
Returns
|
68
70
|
-------
|
69
71
|
A pandas DataFrame or `None`.
|
@@ -71,20 +73,20 @@ def fetch(
|
|
71
73
|
"""
|
72
74
|
meta_def = self.get_pipe_metadef(
|
73
75
|
pipe,
|
74
|
-
begin
|
75
|
-
end
|
76
|
-
check_existing
|
77
|
-
debug
|
76
|
+
begin=begin,
|
77
|
+
end=end,
|
78
|
+
check_existing=check_existing,
|
79
|
+
debug=debug,
|
78
80
|
**kw
|
79
81
|
)
|
80
82
|
as_hook_results = chunk_hook is not None
|
81
83
|
chunks = self.read(
|
82
84
|
meta_def,
|
83
|
-
chunk_hook
|
84
|
-
as_hook_results
|
85
|
-
chunksize
|
86
|
-
workers
|
87
|
-
debug
|
85
|
+
chunk_hook=chunk_hook,
|
86
|
+
as_hook_results=as_hook_results,
|
87
|
+
chunksize=chunksize,
|
88
|
+
workers=workers,
|
89
|
+
debug=debug,
|
88
90
|
)
|
89
91
|
### if sqlite, parse for datetimes
|
90
92
|
if not as_hook_results and self.flavor == 'sqlite':
|
@@ -97,8 +99,8 @@ def fetch(
|
|
97
99
|
return (
|
98
100
|
parse_df_datetimes(
|
99
101
|
chunk,
|
100
|
-
ignore_cols
|
101
|
-
debug
|
102
|
+
ignore_cols=ignore_cols,
|
103
|
+
debug=debug,
|
102
104
|
)
|
103
105
|
for chunk in chunks
|
104
106
|
)
|
@@ -106,15 +108,15 @@ def fetch(
|
|
106
108
|
|
107
109
|
|
108
110
|
def get_pipe_metadef(
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
111
|
+
self,
|
112
|
+
pipe: mrsm.Pipe,
|
113
|
+
params: Optional[Dict[str, Any]] = None,
|
114
|
+
begin: Union[datetime, int, str, None] = '',
|
115
|
+
end: Union[datetime, int, str, None] = None,
|
116
|
+
check_existing: bool = True,
|
117
|
+
debug: bool = False,
|
118
|
+
**kw: Any
|
119
|
+
) -> Union[str, None]:
|
118
120
|
"""
|
119
121
|
Return a pipe's meta definition fetch query.
|
120
122
|
|
@@ -173,7 +175,6 @@ def get_pipe_metadef(
|
|
173
175
|
stack = False
|
174
176
|
)
|
175
177
|
|
176
|
-
|
177
178
|
apply_backtrack = begin == '' and check_existing
|
178
179
|
backtrack_interval = pipe.get_backtrack_interval(check_existing=check_existing, debug=debug)
|
179
180
|
btm = (
|
@@ -189,35 +190,34 @@ def get_pipe_metadef(
|
|
189
190
|
|
190
191
|
if begin and end and begin >= end:
|
191
192
|
begin = None
|
192
|
-
|
193
|
-
da = None
|
193
|
+
|
194
194
|
if dt_name:
|
195
195
|
begin_da = (
|
196
196
|
dateadd_str(
|
197
|
-
flavor
|
198
|
-
datepart
|
199
|
-
number
|
200
|
-
begin
|
197
|
+
flavor=self.flavor,
|
198
|
+
datepart='minute',
|
199
|
+
number=((-1 * btm) if apply_backtrack else 0),
|
200
|
+
begin=begin,
|
201
201
|
)
|
202
202
|
if begin
|
203
203
|
else None
|
204
204
|
)
|
205
205
|
end_da = (
|
206
206
|
dateadd_str(
|
207
|
-
flavor
|
208
|
-
datepart
|
209
|
-
number
|
210
|
-
begin
|
207
|
+
flavor=self.flavor,
|
208
|
+
datepart='minute',
|
209
|
+
number=0,
|
210
|
+
begin=end,
|
211
211
|
)
|
212
212
|
if end
|
213
213
|
else None
|
214
214
|
)
|
215
215
|
|
216
216
|
meta_def = (
|
217
|
-
_simple_fetch_query(pipe) if (
|
217
|
+
_simple_fetch_query(pipe, self.flavor) if (
|
218
218
|
(not (pipe.columns or {}).get('id', None))
|
219
219
|
or (not get_config('system', 'experimental', 'join_fetch'))
|
220
|
-
) else _join_fetch_query(pipe, debug=debug, **kw)
|
220
|
+
) else _join_fetch_query(pipe, self.flavor, debug=debug, **kw)
|
221
221
|
)
|
222
222
|
|
223
223
|
has_where = 'where' in meta_def.lower()[meta_def.lower().rfind('definition'):]
|
@@ -300,25 +300,28 @@ def set_pipe_query(pipe: mrsm.Pipe, query: str) -> None:
|
|
300
300
|
dict_to_set[key_to_set] = query
|
301
301
|
|
302
302
|
|
303
|
-
def _simple_fetch_query(
|
303
|
+
def _simple_fetch_query(
|
304
|
+
pipe: mrsm.Pipe,
|
305
|
+
flavor: str,
|
306
|
+
debug: bool = False,
|
307
|
+
**kw
|
308
|
+
) -> str:
|
304
309
|
"""Build a fetch query from a pipe's definition."""
|
305
|
-
|
310
|
+
from meerschaum.utils.sql import format_cte_subquery
|
306
311
|
definition = get_pipe_query(pipe)
|
307
|
-
return (
|
308
|
-
|
309
|
-
if pipe.connector.flavor not in ('mysql', 'mariadb')
|
310
|
-
else f"SELECT * FROM (\n{definition}\n) AS {def_name}"
|
311
|
-
)
|
312
|
+
return format_cte_subquery(definition, flavor, 'definition')
|
313
|
+
|
312
314
|
|
313
315
|
def _join_fetch_query(
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
316
|
+
pipe: mrsm.Pipe,
|
317
|
+
flavor: str,
|
318
|
+
debug: bool = False,
|
319
|
+
new_ids: bool = True,
|
320
|
+
**kw
|
321
|
+
) -> str:
|
319
322
|
"""Build a fetch query based on the datetime and ID indices."""
|
320
323
|
if not pipe.exists(debug=debug):
|
321
|
-
return _simple_fetch_query(pipe, debug=debug, **kw)
|
324
|
+
return _simple_fetch_query(pipe, flavor, debug=debug, **kw)
|
322
325
|
|
323
326
|
from meerschaum.utils.sql import sql_item_name, dateadd_str
|
324
327
|
pipe_instance_name = sql_item_name(
|
@@ -350,7 +353,8 @@ def _join_fetch_query(
|
|
350
353
|
"""
|
351
354
|
sync_times = pipe.instance_connector.read(sync_times_query, debug=debug, silent=False)
|
352
355
|
if sync_times is None:
|
353
|
-
return _simple_fetch_query(pipe, debug=debug, **kw)
|
356
|
+
return _simple_fetch_query(pipe, flavor, debug=debug, **kw)
|
357
|
+
|
354
358
|
_sync_times_q = f",\n{sync_times_remote_name} AS ("
|
355
359
|
for _id, _st in sync_times.itertuples(index=False):
|
356
360
|
_sync_times_q += (
|