meerschaum 2.9.4__py3-none-any.whl → 3.0.0rc1__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/__init__.py +5 -2
- meerschaum/_internal/__init__.py +1 -0
- meerschaum/_internal/arguments/_parse_arguments.py +4 -4
- meerschaum/_internal/arguments/_parser.py +17 -1
- meerschaum/_internal/entry.py +6 -6
- meerschaum/_internal/shell/Shell.py +1 -1
- meerschaum/_internal/static.py +372 -0
- meerschaum/actions/api.py +12 -2
- meerschaum/actions/bootstrap.py +7 -7
- meerschaum/actions/edit.py +142 -18
- meerschaum/actions/register.py +137 -6
- meerschaum/actions/show.py +117 -29
- meerschaum/actions/stop.py +4 -1
- meerschaum/actions/sync.py +1 -1
- meerschaum/actions/tag.py +9 -8
- meerschaum/api/__init__.py +9 -2
- meerschaum/api/_events.py +39 -2
- meerschaum/api/_oauth2.py +118 -8
- meerschaum/api/_tokens.py +102 -0
- meerschaum/api/dash/__init__.py +0 -1
- meerschaum/api/dash/callbacks/custom.py +2 -2
- meerschaum/api/dash/callbacks/dashboard.py +133 -18
- meerschaum/api/dash/callbacks/plugins.py +0 -1
- meerschaum/api/dash/callbacks/register.py +1 -1
- meerschaum/api/dash/callbacks/settings/__init__.py +1 -0
- meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
- meerschaum/api/dash/callbacks/settings/tokens.py +388 -0
- meerschaum/api/dash/components.py +30 -8
- meerschaum/api/dash/keys.py +19 -93
- meerschaum/api/dash/pages/dashboard.py +1 -20
- meerschaum/api/dash/pages/settings/__init__.py +1 -0
- meerschaum/api/dash/pages/settings/password_reset.py +1 -1
- meerschaum/api/dash/pages/settings/tokens.py +55 -0
- meerschaum/api/dash/pipes.py +156 -58
- meerschaum/api/dash/sessions.py +12 -0
- meerschaum/api/dash/tokens.py +606 -0
- meerschaum/api/dash/websockets.py +1 -1
- meerschaum/api/dash/webterm.py +4 -0
- meerschaum/api/models/__init__.py +23 -3
- meerschaum/api/models/_actions.py +22 -0
- meerschaum/api/models/_pipes.py +85 -7
- meerschaum/api/models/_tokens.py +81 -0
- meerschaum/api/resources/static/css/dash.css +16 -0
- meerschaum/api/resources/templates/termpage.html +12 -0
- meerschaum/api/routes/__init__.py +1 -0
- meerschaum/api/routes/_actions.py +3 -4
- meerschaum/api/routes/_connectors.py +3 -7
- meerschaum/api/routes/_jobs.py +14 -35
- meerschaum/api/routes/_login.py +49 -12
- meerschaum/api/routes/_misc.py +5 -10
- meerschaum/api/routes/_pipes.py +134 -111
- meerschaum/api/routes/_plugins.py +38 -28
- meerschaum/api/routes/_tokens.py +236 -0
- meerschaum/api/routes/_users.py +47 -35
- meerschaum/api/routes/_version.py +3 -3
- meerschaum/config/__init__.py +43 -20
- meerschaum/config/_default.py +32 -5
- meerschaum/config/_edit.py +28 -24
- meerschaum/config/_environment.py +1 -1
- meerschaum/config/_patch.py +6 -6
- meerschaum/config/_paths.py +5 -1
- meerschaum/config/_read_config.py +65 -34
- meerschaum/config/_sync.py +6 -3
- meerschaum/config/_version.py +1 -1
- meerschaum/config/stack/__init__.py +24 -5
- meerschaum/config/static.py +18 -0
- meerschaum/connectors/_Connector.py +10 -4
- meerschaum/connectors/__init__.py +4 -20
- meerschaum/connectors/api/_APIConnector.py +34 -6
- meerschaum/connectors/api/_actions.py +2 -2
- meerschaum/connectors/api/_jobs.py +1 -1
- meerschaum/connectors/api/_login.py +33 -7
- meerschaum/connectors/api/_misc.py +2 -2
- meerschaum/connectors/api/_pipes.py +15 -14
- meerschaum/connectors/api/_plugins.py +2 -2
- meerschaum/connectors/api/_request.py +1 -1
- meerschaum/connectors/api/_tokens.py +146 -0
- meerschaum/connectors/api/_users.py +70 -58
- meerschaum/connectors/instance/_InstanceConnector.py +83 -0
- meerschaum/connectors/instance/__init__.py +10 -0
- meerschaum/connectors/instance/_pipes.py +442 -0
- meerschaum/connectors/instance/_plugins.py +151 -0
- meerschaum/connectors/instance/_tokens.py +296 -0
- meerschaum/connectors/instance/_users.py +181 -0
- meerschaum/connectors/parse.py +4 -1
- meerschaum/connectors/sql/_SQLConnector.py +8 -5
- meerschaum/connectors/sql/_cli.py +12 -11
- meerschaum/connectors/sql/_create_engine.py +6 -154
- meerschaum/connectors/sql/_fetch.py +2 -18
- meerschaum/connectors/sql/_pipes.py +42 -31
- meerschaum/connectors/sql/_plugins.py +29 -0
- meerschaum/connectors/sql/_sql.py +9 -2
- meerschaum/connectors/sql/_users.py +29 -2
- meerschaum/connectors/sql/tables/__init__.py +1 -1
- meerschaum/connectors/valkey/_ValkeyConnector.py +2 -4
- meerschaum/connectors/valkey/_pipes.py +9 -10
- meerschaum/connectors/valkey/_plugins.py +2 -26
- meerschaum/core/Pipe/__init__.py +31 -14
- meerschaum/core/Pipe/_attributes.py +156 -58
- meerschaum/core/Pipe/_bootstrap.py +54 -24
- meerschaum/core/Pipe/_data.py +41 -1
- meerschaum/core/Pipe/_dtypes.py +29 -14
- meerschaum/core/Pipe/_edit.py +12 -4
- meerschaum/core/Pipe/_show.py +5 -5
- meerschaum/core/Pipe/_sync.py +48 -53
- meerschaum/core/Pipe/_verify.py +1 -1
- meerschaum/{plugins → core/Plugin}/_Plugin.py +9 -11
- meerschaum/core/Plugin/__init__.py +1 -1
- meerschaum/core/Token/_Token.py +221 -0
- meerschaum/core/Token/__init__.py +12 -0
- meerschaum/core/User/_User.py +34 -8
- meerschaum/core/User/__init__.py +9 -1
- meerschaum/core/__init__.py +1 -0
- meerschaum/jobs/_Job.py +3 -2
- meerschaum/jobs/__init__.py +3 -2
- meerschaum/jobs/systemd.py +1 -1
- meerschaum/models/__init__.py +35 -0
- meerschaum/models/pipes.py +247 -0
- meerschaum/models/tokens.py +38 -0
- meerschaum/models/users.py +26 -0
- meerschaum/plugins/__init__.py +22 -7
- meerschaum/plugins/bootstrap.py +2 -1
- meerschaum/utils/_get_pipes.py +68 -27
- meerschaum/utils/daemon/Daemon.py +2 -1
- meerschaum/utils/daemon/__init__.py +30 -2
- meerschaum/utils/dataframe.py +96 -15
- meerschaum/utils/dtypes/__init__.py +93 -21
- meerschaum/utils/dtypes/sql.py +44 -0
- meerschaum/utils/formatting/__init__.py +1 -1
- meerschaum/utils/formatting/_pipes.py +5 -4
- meerschaum/utils/formatting/_shell.py +11 -9
- meerschaum/utils/misc.py +237 -80
- meerschaum/utils/packages/__init__.py +3 -6
- meerschaum/utils/packages/_packages.py +34 -32
- meerschaum/utils/pipes.py +181 -0
- meerschaum/utils/process.py +1 -1
- meerschaum/utils/prompt.py +3 -1
- meerschaum/utils/schedule.py +1 -0
- meerschaum/utils/sql.py +115 -39
- meerschaum/utils/typing.py +1 -4
- meerschaum/utils/venv/_Venv.py +2 -2
- meerschaum/utils/venv/__init__.py +5 -7
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/METADATA +88 -80
- meerschaum-3.0.0rc1.dist-info/RECORD +282 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/WHEEL +1 -1
- meerschaum/api/models/_interfaces.py +0 -15
- meerschaum/api/models/_locations.py +0 -15
- meerschaum/api/models/_metrics.py +0 -15
- meerschaum/config/static/__init__.py +0 -186
- meerschaum-2.9.4.dist-info/RECORD +0 -263
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/top_level.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/zip-safe +0 -0
@@ -0,0 +1,181 @@
|
|
1
|
+
#! /usr/bin/env python3
|
2
|
+
# vim:fenc=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
Define utilities for working with pipes.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from __future__ import annotations
|
9
|
+
|
10
|
+
from typing import Any, Dict, Callable
|
11
|
+
import re
|
12
|
+
import json
|
13
|
+
import ast
|
14
|
+
import copy
|
15
|
+
import uuid
|
16
|
+
|
17
|
+
from meerschaum.utils.typing import PipesDict, Optional, Any
|
18
|
+
import meerschaum as mrsm
|
19
|
+
|
20
|
+
|
21
|
+
def evaluate_pipe_access_chain(access_chain: str, pipe: mrsm.Pipe):
|
22
|
+
"""
|
23
|
+
Safely evaluate the access chain on a Pipe.
|
24
|
+
"""
|
25
|
+
expr = f"pipe{access_chain}"
|
26
|
+
tree = ast.parse(expr, mode='eval')
|
27
|
+
|
28
|
+
def _eval(node, context):
|
29
|
+
if isinstance(node, ast.Expression):
|
30
|
+
return _eval(node.body, context)
|
31
|
+
|
32
|
+
elif isinstance(node, ast.Name):
|
33
|
+
if node.id == "pipe":
|
34
|
+
return context
|
35
|
+
raise ValueError(f"Unknown variable: {node.id}")
|
36
|
+
|
37
|
+
elif isinstance(node, ast.Attribute):
|
38
|
+
value = _eval(node.value, context)
|
39
|
+
return getattr(value, node.attr)
|
40
|
+
|
41
|
+
elif isinstance(node, ast.Subscript):
|
42
|
+
value = _eval(node.value, context)
|
43
|
+
key = _eval(node.slice, context) if isinstance(node.slice, ast.Index) else _eval(node.slice, context)
|
44
|
+
return value[key]
|
45
|
+
|
46
|
+
elif isinstance(node, ast.Constant): # Python 3.8+
|
47
|
+
return node.value
|
48
|
+
|
49
|
+
elif isinstance(node, ast.Str): # Older Python
|
50
|
+
return node.s
|
51
|
+
|
52
|
+
elif isinstance(node, ast.Index): # Older Python AST style
|
53
|
+
return _eval(node.value, context)
|
54
|
+
|
55
|
+
else:
|
56
|
+
raise TypeError(f"Unsupported AST node: {ast.dump(node)}")
|
57
|
+
|
58
|
+
return _eval(tree, pipe)
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
def _evaluate_pipe_access_chain_from_match(pipe_match: re.Match) -> Any:
|
63
|
+
"""
|
64
|
+
Helper function to evaluate a pipe from a regex match object.
|
65
|
+
"""
|
66
|
+
from meerschaum.utils.warnings import warn
|
67
|
+
from meerschaum.utils.misc import parse_arguments_str
|
68
|
+
from meerschaum.utils.sql import sql_item_name
|
69
|
+
try:
|
70
|
+
args_str = pipe_match.group(1)
|
71
|
+
access_chain = pipe_match.group(2)
|
72
|
+
args, kwargs = parse_arguments_str(args_str)
|
73
|
+
pipe = mrsm.Pipe(*args, **kwargs)
|
74
|
+
except Exception as e:
|
75
|
+
warn(f"Failed to parse pipe from template string:\n{e}")
|
76
|
+
raise e
|
77
|
+
|
78
|
+
if not access_chain:
|
79
|
+
target = pipe.target
|
80
|
+
schema = (
|
81
|
+
pipe.instance_connector.get_pipe_schema(pipe)
|
82
|
+
if hasattr(pipe.instance_connector, 'get_pipe_schema')
|
83
|
+
else None
|
84
|
+
)
|
85
|
+
return (
|
86
|
+
sql_item_name(target, pipe.instance_connector.flavor, schema)
|
87
|
+
if pipe.instance_connector.type == 'sql'
|
88
|
+
else pipe.target
|
89
|
+
)
|
90
|
+
|
91
|
+
return evaluate_pipe_access_chain(access_chain, pipe)
|
92
|
+
|
93
|
+
|
94
|
+
def replace_pipes_syntax(text: str) -> Any:
|
95
|
+
"""
|
96
|
+
Parse a string containing the `{{ Pipe() }}` syntax.
|
97
|
+
"""
|
98
|
+
from meerschaum.utils.warnings import warn
|
99
|
+
from meerschaum.utils.sql import sql_item_name
|
100
|
+
from meerschaum.utils.dtypes import json_serialize_value
|
101
|
+
from meerschaum.utils.misc import parse_arguments_str
|
102
|
+
pattern = r'\{\{\s*(?:mrsm\.)?Pipe\((.*?)\)((?:\.[\w]+|\[[^\]]+\])*)\s*\}\}'
|
103
|
+
|
104
|
+
matches = list(re.finditer(pattern, text))
|
105
|
+
if not matches:
|
106
|
+
return text
|
107
|
+
|
108
|
+
placeholders = {}
|
109
|
+
for match in matches:
|
110
|
+
placeholder = f"__mrsm_pipe_placeholder_{uuid.uuid4().hex}__"
|
111
|
+
placeholders[placeholder] = match
|
112
|
+
|
113
|
+
substituted_text = text
|
114
|
+
for placeholder, match in placeholders.items():
|
115
|
+
substituted_text = substituted_text.replace(match.group(0), placeholder)
|
116
|
+
|
117
|
+
resolved_values = {}
|
118
|
+
for placeholder, match in placeholders.items():
|
119
|
+
try:
|
120
|
+
resolved_values[placeholder] = _evaluate_pipe_access_chain_from_match(match)
|
121
|
+
except Exception as e:
|
122
|
+
warn(f"Failed to resolve pipe syntax '{match.group(0)}': {e}")
|
123
|
+
resolved_values[placeholder] = match.group(0)
|
124
|
+
|
125
|
+
if len(matches) == 1:
|
126
|
+
match = matches[0]
|
127
|
+
placeholder = list(placeholders.keys())[0]
|
128
|
+
if text.strip() == match.group(0):
|
129
|
+
return resolved_values[placeholder]
|
130
|
+
|
131
|
+
final_text = substituted_text
|
132
|
+
for placeholder, value in resolved_values.items():
|
133
|
+
if isinstance(value, (dict, list, bool, int, float)) or value is None:
|
134
|
+
final_text = final_text.replace(placeholder, json.dumps(value, default=json_serialize_value))
|
135
|
+
else:
|
136
|
+
final_text = final_text.replace(placeholder, str(value))
|
137
|
+
|
138
|
+
return final_text
|
139
|
+
|
140
|
+
|
141
|
+
def replace_pipes_in_dict(
|
142
|
+
pipes: Optional[PipesDict] = None,
|
143
|
+
func: Callable[[Any], Any] = str,
|
144
|
+
debug: bool = False,
|
145
|
+
**kw
|
146
|
+
) -> PipesDict:
|
147
|
+
"""
|
148
|
+
Replace the Pipes in a Pipes dict with the result of another function.
|
149
|
+
|
150
|
+
Parameters
|
151
|
+
----------
|
152
|
+
pipes: Optional[PipesDict], default None
|
153
|
+
The pipes dict to be processed.
|
154
|
+
|
155
|
+
func: Callable[[Any], Any], default str
|
156
|
+
The function to be applied to every pipe.
|
157
|
+
Defaults to the string constructor.
|
158
|
+
|
159
|
+
debug: bool, default False
|
160
|
+
Verbosity toggle.
|
161
|
+
|
162
|
+
|
163
|
+
Returns
|
164
|
+
-------
|
165
|
+
A dictionary where every pipe is replaced with the output of a function.
|
166
|
+
|
167
|
+
"""
|
168
|
+
def change_dict(d : Dict[Any, Any], func : 'function') -> None:
|
169
|
+
for k, v in d.items():
|
170
|
+
if isinstance(v, dict):
|
171
|
+
change_dict(v, func)
|
172
|
+
else:
|
173
|
+
d[k] = func(v)
|
174
|
+
|
175
|
+
if pipes is None:
|
176
|
+
from meerschaum import get_pipes
|
177
|
+
pipes = get_pipes(debug=debug, **kw)
|
178
|
+
|
179
|
+
result = copy.deepcopy(pipes)
|
180
|
+
change_dict(result, func)
|
181
|
+
return result
|
meerschaum/utils/process.py
CHANGED
@@ -18,7 +18,7 @@ import platform
|
|
18
18
|
|
19
19
|
import meerschaum as mrsm
|
20
20
|
from meerschaum.utils.typing import Union, Optional, Any, Callable, Dict, Tuple
|
21
|
-
from meerschaum.
|
21
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
22
22
|
|
23
23
|
_child_processes = []
|
24
24
|
def signal_handler(sig, frame):
|
meerschaum/utils/prompt.py
CHANGED
@@ -399,6 +399,8 @@ def choose(
|
|
399
399
|
noask = noask,
|
400
400
|
**kw
|
401
401
|
)
|
402
|
+
if not answer:
|
403
|
+
continue
|
402
404
|
### Split along the delimiter.
|
403
405
|
_answers = [answer] if not multiple else [a for a in answer.split(delimiter)]
|
404
406
|
|
@@ -564,7 +566,7 @@ def check_noask(noask: bool = False) -> bool:
|
|
564
566
|
"""
|
565
567
|
Flip `noask` to `True` if `MRSM_NOASK` is set.
|
566
568
|
"""
|
567
|
-
from meerschaum.
|
569
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
568
570
|
NOASK = STATIC_CONFIG['environment']['noask']
|
569
571
|
if noask:
|
570
572
|
return True
|
meerschaum/utils/schedule.py
CHANGED
@@ -14,6 +14,7 @@ import meerschaum as mrsm
|
|
14
14
|
from meerschaum.utils.typing import Callable, Any, Optional, List, Dict
|
15
15
|
from meerschaum.utils.warnings import warn, error
|
16
16
|
|
17
|
+
|
17
18
|
STARTING_KEYWORD: str = 'starting'
|
18
19
|
INTERVAL_UNITS: List[str] = ['months', 'weeks', 'days', 'hours', 'minutes', 'seconds', 'years']
|
19
20
|
FREQUENCY_ALIASES: Dict[str, str] = {
|
meerschaum/utils/sql.py
CHANGED
@@ -41,13 +41,33 @@ version_queries = {
|
|
41
41
|
}
|
42
42
|
SKIP_IF_EXISTS_FLAVORS = {'mssql', 'oracle'}
|
43
43
|
DROP_IF_EXISTS_FLAVORS = {
|
44
|
-
'timescaledb',
|
44
|
+
'timescaledb',
|
45
|
+
'timescaledb-ha',
|
46
|
+
'postgresql',
|
47
|
+
'postgis',
|
48
|
+
'citus',
|
49
|
+
'mssql',
|
50
|
+
'mysql',
|
51
|
+
'mariadb',
|
52
|
+
'sqlite',
|
45
53
|
}
|
46
54
|
DROP_INDEX_IF_EXISTS_FLAVORS = {
|
47
|
-
'mssql',
|
55
|
+
'mssql',
|
56
|
+
'timescaledb',
|
57
|
+
'timescaledb-ha',
|
58
|
+
'postgresql',
|
59
|
+
'postgis',
|
60
|
+
'sqlite',
|
61
|
+
'citus',
|
48
62
|
}
|
49
63
|
SKIP_AUTO_INCREMENT_FLAVORS = {'citus', 'duckdb'}
|
50
|
-
COALESCE_UNIQUE_INDEX_FLAVORS = {
|
64
|
+
COALESCE_UNIQUE_INDEX_FLAVORS = {
|
65
|
+
'timescaledb',
|
66
|
+
'timescaledb-ha',
|
67
|
+
'postgresql',
|
68
|
+
'postgis',
|
69
|
+
'citus',
|
70
|
+
}
|
51
71
|
UPDATE_QUERIES = {
|
52
72
|
'default': """
|
53
73
|
UPDATE {target_table_name} AS f
|
@@ -67,6 +87,12 @@ UPDATE_QUERIES = {
|
|
67
87
|
FROM {patch_table_name}
|
68
88
|
ON CONFLICT ({join_cols_str}) DO {update_or_nothing} {sets_subquery_none_excluded}
|
69
89
|
""",
|
90
|
+
'timescaledb-ha-upsert': """
|
91
|
+
INSERT INTO {target_table_name} ({patch_cols_str})
|
92
|
+
SELECT {patch_cols_str}
|
93
|
+
FROM {patch_table_name}
|
94
|
+
ON CONFLICT ({join_cols_str}) DO {update_or_nothing} {sets_subquery_none_excluded}
|
95
|
+
""",
|
70
96
|
'postgresql-upsert': """
|
71
97
|
INSERT INTO {target_table_name} ({patch_cols_str})
|
72
98
|
SELECT {patch_cols_str}
|
@@ -286,6 +312,7 @@ columns_types_queries = {
|
|
286
312
|
}
|
287
313
|
hypertable_queries = {
|
288
314
|
'timescaledb': 'SELECT hypertable_size(\'{table_name}\')',
|
315
|
+
'timescaledb-ha': 'SELECT hypertable_size(\'{table_name}\')',
|
289
316
|
'citus': 'SELECT citus_table_size(\'{table_name}\')',
|
290
317
|
}
|
291
318
|
columns_indices_queries = {
|
@@ -483,49 +510,83 @@ reset_autoincrement_queries: Dict[str, Union[str, List[str]]] = {
|
|
483
510
|
),
|
484
511
|
}
|
485
512
|
table_wrappers = {
|
486
|
-
'default'
|
487
|
-
'timescaledb': ('"', '"'),
|
488
|
-
'
|
489
|
-
'
|
490
|
-
'
|
491
|
-
'
|
492
|
-
'
|
493
|
-
'
|
494
|
-
'
|
495
|
-
'
|
496
|
-
'
|
497
|
-
'
|
513
|
+
'default' : ('"', '"'),
|
514
|
+
'timescaledb' : ('"', '"'),
|
515
|
+
'timescaledb-ha': ('"', '"'),
|
516
|
+
'citus' : ('"', '"'),
|
517
|
+
'duckdb' : ('"', '"'),
|
518
|
+
'postgresql' : ('"', '"'),
|
519
|
+
'postgis' : ('"', '"'),
|
520
|
+
'sqlite' : ('"', '"'),
|
521
|
+
'mysql' : ('`', '`'),
|
522
|
+
'mariadb' : ('`', '`'),
|
523
|
+
'mssql' : ('[', ']'),
|
524
|
+
'cockroachdb' : ('"', '"'),
|
525
|
+
'oracle' : ('"', '"'),
|
498
526
|
}
|
499
527
|
max_name_lens = {
|
500
|
-
'default'
|
501
|
-
'mssql'
|
502
|
-
'oracle'
|
503
|
-
'postgresql'
|
504
|
-
'postgis'
|
505
|
-
'timescaledb': 64,
|
506
|
-
'
|
507
|
-
'
|
508
|
-
'
|
509
|
-
'
|
510
|
-
'
|
528
|
+
'default' : 64,
|
529
|
+
'mssql' : 128,
|
530
|
+
'oracle' : 30,
|
531
|
+
'postgresql' : 64,
|
532
|
+
'postgis' : 64,
|
533
|
+
'timescaledb' : 64,
|
534
|
+
'timescaledb-ha': 64,
|
535
|
+
'citus' : 64,
|
536
|
+
'cockroachdb' : 64,
|
537
|
+
'sqlite' : 1024, ### Probably more, but 1024 seems more than reasonable.
|
538
|
+
'mysql' : 64,
|
539
|
+
'mariadb' : 64,
|
540
|
+
}
|
541
|
+
json_flavors = {
|
542
|
+
'postgresql',
|
543
|
+
'postgis',
|
544
|
+
'timescaledb',
|
545
|
+
'timescaledb-ha',
|
546
|
+
'citus',
|
547
|
+
'cockroachdb',
|
548
|
+
}
|
549
|
+
NO_SCHEMA_FLAVORS = {
|
550
|
+
'oracle',
|
551
|
+
'sqlite',
|
552
|
+
'mysql',
|
553
|
+
'mariadb',
|
554
|
+
'duckdb',
|
511
555
|
}
|
512
|
-
json_flavors = {'postgresql', 'postgis', 'timescaledb', 'citus', 'cockroachdb'}
|
513
|
-
NO_SCHEMA_FLAVORS = {'oracle', 'sqlite', 'mysql', 'mariadb', 'duckdb'}
|
514
556
|
DEFAULT_SCHEMA_FLAVORS = {
|
515
557
|
'postgresql': 'public',
|
516
558
|
'postgis': 'public',
|
517
559
|
'timescaledb': 'public',
|
560
|
+
'timescaledb-ha': 'public',
|
518
561
|
'citus': 'public',
|
519
562
|
'cockroachdb': 'public',
|
520
563
|
'mysql': 'mysql',
|
521
564
|
'mariadb': 'mysql',
|
522
565
|
'mssql': 'dbo',
|
523
566
|
}
|
524
|
-
OMIT_NULLSFIRST_FLAVORS = {
|
567
|
+
OMIT_NULLSFIRST_FLAVORS = {
|
568
|
+
'mariadb',
|
569
|
+
'mysql',
|
570
|
+
'mssql',
|
571
|
+
}
|
525
572
|
|
526
|
-
SINGLE_ALTER_TABLE_FLAVORS = {
|
527
|
-
|
528
|
-
|
573
|
+
SINGLE_ALTER_TABLE_FLAVORS = {
|
574
|
+
'duckdb',
|
575
|
+
'sqlite',
|
576
|
+
'mssql',
|
577
|
+
'oracle',
|
578
|
+
}
|
579
|
+
NO_CTE_FLAVORS = {
|
580
|
+
'mysql',
|
581
|
+
'mariadb',
|
582
|
+
}
|
583
|
+
NO_SELECT_INTO_FLAVORS = {
|
584
|
+
'sqlite',
|
585
|
+
'oracle',
|
586
|
+
'mysql',
|
587
|
+
'mariadb',
|
588
|
+
'duckdb',
|
589
|
+
}
|
529
590
|
|
530
591
|
|
531
592
|
def clean(substring: str) -> None:
|
@@ -560,6 +621,7 @@ def dateadd_str(
|
|
560
621
|
- `'postgresql'`
|
561
622
|
- `'postgis'`
|
562
623
|
- `'timescaledb'`
|
624
|
+
- `'timescaledb-ha'`
|
563
625
|
- `'citus'`
|
564
626
|
- `'cockroachdb'`
|
565
627
|
- `'duckdb'`
|
@@ -663,7 +725,14 @@ def dateadd_str(
|
|
663
725
|
)
|
664
726
|
|
665
727
|
da = ""
|
666
|
-
if flavor in (
|
728
|
+
if flavor in (
|
729
|
+
'postgresql',
|
730
|
+
'postgis',
|
731
|
+
'timescaledb',
|
732
|
+
'timescaledb-ha',
|
733
|
+
'cockroachdb',
|
734
|
+
'citus',
|
735
|
+
):
|
667
736
|
begin = (
|
668
737
|
f"CAST({begin} AS {db_type})" if begin != 'now'
|
669
738
|
else f"CAST(NOW() AT TIME ZONE 'utc' AS {db_type})"
|
@@ -969,7 +1038,7 @@ def build_where(
|
|
969
1038
|
```
|
970
1039
|
"""
|
971
1040
|
import json
|
972
|
-
from meerschaum.
|
1041
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
973
1042
|
from meerschaum.utils.warnings import warn
|
974
1043
|
from meerschaum.utils.dtypes import value_is_null, none_if_null
|
975
1044
|
negation_prefix = STATIC_CONFIG['system']['fetch_pipes_keys']['negation_prefix']
|
@@ -1838,10 +1907,9 @@ def get_null_replacement(typ: str, flavor: str) -> str:
|
|
1838
1907
|
A value which may stand in place of NULL for this type.
|
1839
1908
|
`'None'` is returned if a value cannot be determined.
|
1840
1909
|
"""
|
1841
|
-
from meerschaum.utils.dtypes import are_dtypes_equal
|
1842
1910
|
from meerschaum.utils.dtypes.sql import DB_FLAVORS_CAST_DTYPES
|
1843
1911
|
if 'geometry' in typ.lower():
|
1844
|
-
return '010100000000008058346FCDC100008058346FCDC1'
|
1912
|
+
return "'010100000000008058346FCDC100008058346FCDC1'"
|
1845
1913
|
if 'int' in typ.lower() or typ.lower() in ('numeric', 'number'):
|
1846
1914
|
return '-987654321'
|
1847
1915
|
if 'bool' in typ.lower() or typ.lower() == 'bit':
|
@@ -2113,7 +2181,11 @@ def _get_create_table_query_from_dtypes(
|
|
2113
2181
|
)
|
2114
2182
|
elif flavor == 'oracle':
|
2115
2183
|
query += f"\n {col_name} {col_db_type} {auto_increment_str} PRIMARY KEY,"
|
2116
|
-
elif
|
2184
|
+
elif (
|
2185
|
+
flavor in ('timescaledb', 'timescaledb-ha')
|
2186
|
+
and datetime_column
|
2187
|
+
and datetime_column != primary_key
|
2188
|
+
):
|
2117
2189
|
query += f"\n {col_name} {col_db_type}{auto_increment_str} NOT NULL,"
|
2118
2190
|
elif flavor == 'mssql':
|
2119
2191
|
query += f"\n {col_name} {col_db_type}{auto_increment_str} NOT NULL,"
|
@@ -2126,7 +2198,7 @@ def _get_create_table_query_from_dtypes(
|
|
2126
2198
|
col_name = sql_item_name(col, schema=None, flavor=flavor)
|
2127
2199
|
query += f"\n {col_name} {db_type},"
|
2128
2200
|
if (
|
2129
|
-
flavor
|
2201
|
+
flavor in ('timescaledb', 'timescaledb-ha')
|
2130
2202
|
and datetime_column
|
2131
2203
|
and primary_key
|
2132
2204
|
and datetime_column != primary_key
|
@@ -2249,7 +2321,11 @@ def _get_create_table_query_from_cte(
|
|
2249
2321
|
"ADD PRIMARY KEY ({primary_key_name})"
|
2250
2322
|
),
|
2251
2323
|
]
|
2252
|
-
elif
|
2324
|
+
elif (
|
2325
|
+
flavor in ('timescaledb', 'timescaledb-ha')
|
2326
|
+
and datetime_column
|
2327
|
+
and datetime_column != primary_key
|
2328
|
+
):
|
2253
2329
|
create_table_queries = [
|
2254
2330
|
(
|
2255
2331
|
"SELECT *\n"
|
meerschaum/utils/typing.py
CHANGED
@@ -76,10 +76,7 @@ import collections.abc
|
|
76
76
|
collections.Iterable = collections.abc.Iterable
|
77
77
|
|
78
78
|
SuccessTuple = Tuple[bool, str]
|
79
|
-
InstanceConnector =
|
80
|
-
'meerschaum.connectors.sql.SQLConnector',
|
81
|
-
'meerschaum.connectors.api.APIConnector'
|
82
|
-
]
|
79
|
+
InstanceConnector = 'meerschaum.connectors.InstanceConnector'
|
83
80
|
PipesDict = Dict[
|
84
81
|
str, Dict[ ### connector_keys : metrics
|
85
82
|
str, Dict[ ### metric_key : locations
|
meerschaum/utils/venv/_Venv.py
CHANGED
@@ -35,13 +35,13 @@ class Venv:
|
|
35
35
|
|
36
36
|
def __init__(
|
37
37
|
self,
|
38
|
-
venv: Union[str, 'meerschaum.
|
38
|
+
venv: Union[str, 'meerschaum.core.Plugin', None] = 'mrsm',
|
39
39
|
debug: bool = False,
|
40
40
|
) -> None:
|
41
41
|
from meerschaum.utils.venv import activate_venv, deactivate_venv, active_venvs
|
42
42
|
### For some weird threading issue,
|
43
43
|
### we can't use `isinstance` here.
|
44
|
-
if '
|
44
|
+
if '_Plugin' in str(type(venv)):
|
45
45
|
self._venv = venv.name
|
46
46
|
self._activate = venv.activate_venv
|
47
47
|
self._deactivate = venv.deactivate_venv
|
@@ -8,6 +8,8 @@ Manage virtual environments.
|
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
10
|
|
11
|
+
import pathlib
|
12
|
+
|
11
13
|
from meerschaum.utils.typing import Optional, Union, Dict, List, Tuple
|
12
14
|
from meerschaum.utils.threading import RLock, get_ident
|
13
15
|
|
@@ -229,7 +231,6 @@ def verify_venv(
|
|
229
231
|
"""
|
230
232
|
Verify that the virtual environment matches the expected state.
|
231
233
|
"""
|
232
|
-
import pathlib
|
233
234
|
import platform
|
234
235
|
import os
|
235
236
|
import shutil
|
@@ -382,11 +383,10 @@ def init_venv(
|
|
382
383
|
import sys
|
383
384
|
import platform
|
384
385
|
import os
|
385
|
-
import pathlib
|
386
386
|
import shutil
|
387
387
|
import time
|
388
388
|
|
389
|
-
from meerschaum.
|
389
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
390
390
|
from meerschaum.config._paths import (
|
391
391
|
VIRTENV_RESOURCES_PATH,
|
392
392
|
VENVS_CACHE_RESOURCES_PATH,
|
@@ -682,7 +682,7 @@ def venv_target_path(
|
|
682
682
|
venv: Union[str, None],
|
683
683
|
allow_nonexistent: bool = False,
|
684
684
|
debug: bool = False,
|
685
|
-
) ->
|
685
|
+
) -> pathlib.Path:
|
686
686
|
"""
|
687
687
|
Return a virtual environment's site-package path.
|
688
688
|
|
@@ -702,10 +702,9 @@ def venv_target_path(
|
|
702
702
|
import os
|
703
703
|
import sys
|
704
704
|
import platform
|
705
|
-
import pathlib
|
706
705
|
import site
|
707
706
|
from meerschaum.config._paths import VIRTENV_RESOURCES_PATH
|
708
|
-
from meerschaum.
|
707
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
709
708
|
|
710
709
|
### Check sys.path for a user-writable site-packages directory.
|
711
710
|
if venv is None:
|
@@ -839,7 +838,6 @@ def get_module_venv(module) -> Union[str, None]:
|
|
839
838
|
-------
|
840
839
|
The name of a venv or `None`.
|
841
840
|
"""
|
842
|
-
import pathlib
|
843
841
|
from meerschaum.config.paths import VIRTENV_RESOURCES_PATH
|
844
842
|
module_path = pathlib.Path(module.__file__).resolve()
|
845
843
|
try:
|