meerschaum 2.7.3__py3-none-any.whl → 2.7.5__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/sql.py +14 -4
- meerschaum/actions/start.py +2 -2
- meerschaum/config/_default.py +6 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/sql/_cli.py +18 -12
- meerschaum/connectors/sql/_create_engine.py +1 -0
- meerschaum/connectors/sql/_pipes.py +14 -4
- meerschaum/connectors/sql/_sql.py +100 -15
- meerschaum/jobs/__init__.py +0 -2
- meerschaum/utils/daemon/Daemon.py +7 -3
- meerschaum/utils/daemon/StdinFile.py +4 -1
- meerschaum/utils/packages/__init__.py +4 -1
- meerschaum/utils/venv/_Venv.py +6 -1
- meerschaum/utils/venv/__init__.py +39 -22
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/METADATA +1 -1
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/RECORD +22 -22
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/LICENSE +0 -0
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/NOTICE +0 -0
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/WHEEL +0 -0
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/top_level.txt +0 -0
- {meerschaum-2.7.3.dist-info → meerschaum-2.7.5.dist-info}/zip-safe +0 -0
meerschaum/actions/sql.py
CHANGED
@@ -21,7 +21,7 @@ def sql(
|
|
21
21
|
nopretty: bool = False,
|
22
22
|
debug: bool = False,
|
23
23
|
**kw: Any
|
24
|
-
):
|
24
|
+
) -> SuccessTuple:
|
25
25
|
"""Execute a SQL query or launch an interactive CLI. All positional arguments are optional.
|
26
26
|
|
27
27
|
Usage:
|
@@ -125,10 +125,9 @@ def sql(
|
|
125
125
|
if result is False:
|
126
126
|
return (False, f"Failed to execute query:\n\n{query}")
|
127
127
|
|
128
|
-
from meerschaum.utils.packages import attempt_import
|
128
|
+
from meerschaum.utils.packages import attempt_import
|
129
129
|
from meerschaum.utils.formatting import print_tuple, pprint
|
130
|
-
|
131
|
-
pd = import_pandas()
|
130
|
+
_ = attempt_import('sqlalchemy.engine.result')
|
132
131
|
if 'sqlalchemy' in str(type(result)):
|
133
132
|
if not nopretty:
|
134
133
|
print_tuple((True, f"Successfully executed query:\n\n{query}"))
|
@@ -145,3 +144,14 @@ def sql(
|
|
145
144
|
)
|
146
145
|
|
147
146
|
return (True, "Success")
|
147
|
+
|
148
|
+
|
149
|
+
def _complete_sql(
|
150
|
+
action: Optional[List[str]] = None, **kw: Any
|
151
|
+
) -> List[str]:
|
152
|
+
from meerschaum.utils.misc import get_connector_labels
|
153
|
+
_text = action[0] if action else ""
|
154
|
+
return [
|
155
|
+
label.split('sql:', maxsplit=1)[-1]
|
156
|
+
for label in get_connector_labels('sql', search_term=_text, ignore_exact_match=True)
|
157
|
+
]
|
meerschaum/actions/start.py
CHANGED
@@ -183,7 +183,7 @@ def _start_jobs(
|
|
183
183
|
### Cannot find dameon_id
|
184
184
|
else:
|
185
185
|
msg = (
|
186
|
-
|
186
|
+
"Unknown job" + ('s' if len(action) != 1 else '') + ' '
|
187
187
|
+ items_str(action, and_str='or') + '.'
|
188
188
|
)
|
189
189
|
return False, msg
|
@@ -216,7 +216,7 @@ def _start_jobs(
|
|
216
216
|
return job.start(debug=debug), name
|
217
217
|
|
218
218
|
def _run_existing_job(name: str):
|
219
|
-
job = Job(name, executor_keys=executor_keys)
|
219
|
+
job = jobs.get(name, Job(name, executor_keys=executor_keys))
|
220
220
|
return job.start(debug=debug), name
|
221
221
|
|
222
222
|
if not names:
|
meerschaum/config/_default.py
CHANGED
meerschaum/config/_version.py
CHANGED
@@ -26,46 +26,52 @@ flavor_clis = {
|
|
26
26
|
'duckdb' : 'gadwall',
|
27
27
|
}
|
28
28
|
cli_deps = {
|
29
|
-
'pgcli': ['pgspecial', 'pendulum'],
|
29
|
+
'pgcli': ['pgspecial', 'pendulum', 'cli_helpers'],
|
30
30
|
'mycli': ['cryptography'],
|
31
|
+
'mssql': ['cli_helpers'],
|
31
32
|
}
|
32
33
|
|
33
34
|
|
34
35
|
def cli(
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
self,
|
37
|
+
debug: bool = False,
|
38
|
+
) -> SuccessTuple:
|
38
39
|
"""
|
39
40
|
Launch a subprocess for an interactive CLI.
|
40
41
|
"""
|
42
|
+
from meerschaum.utils.warnings import dprint
|
41
43
|
from meerschaum.utils.venv import venv_exec
|
42
44
|
env = copy.deepcopy(dict(os.environ))
|
43
|
-
|
45
|
+
env_key = f"MRSM_SQL_{self.label.upper()}"
|
46
|
+
env_val = json.dumps(self.meta)
|
47
|
+
env[env_key] = env_val
|
44
48
|
cli_code = (
|
45
49
|
"import sys\n"
|
46
50
|
"import meerschaum as mrsm\n"
|
51
|
+
"import os\n"
|
47
52
|
f"conn = mrsm.get_connector('sql:{self.label}')\n"
|
48
53
|
"success, msg = conn._cli_exit()\n"
|
49
54
|
"mrsm.pprint((success, msg))\n"
|
50
55
|
"if not success:\n"
|
51
56
|
" raise Exception(msg)"
|
52
57
|
)
|
58
|
+
if debug:
|
59
|
+
dprint(cli_code)
|
53
60
|
try:
|
54
|
-
_ = venv_exec(cli_code, venv=None, debug=debug, capture_output=False)
|
61
|
+
_ = venv_exec(cli_code, venv=None, env=env, debug=debug, capture_output=False)
|
55
62
|
except Exception as e:
|
56
63
|
return False, f"[{self}] Failed to start CLI:\n{e}"
|
57
64
|
return True, "Success"
|
58
65
|
|
59
66
|
|
60
67
|
def _cli_exit(
|
61
|
-
|
62
|
-
|
63
|
-
|
68
|
+
self,
|
69
|
+
debug: bool = False
|
70
|
+
) -> SuccessTuple:
|
64
71
|
"""Launch an interactive CLI for the SQLConnector's flavor."""
|
65
|
-
|
72
|
+
import os
|
73
|
+
from meerschaum.utils.packages import attempt_import
|
66
74
|
from meerschaum.utils.debug import dprint
|
67
|
-
from meerschaum.utils.warnings import error
|
68
|
-
import sys, subprocess, os
|
69
75
|
|
70
76
|
if self.flavor not in flavor_clis:
|
71
77
|
return False, f"No CLI available for flavor '{self.flavor}'."
|
@@ -3064,7 +3064,12 @@ def get_alter_columns_queries(
|
|
3064
3064
|
return []
|
3065
3065
|
if pipe.static:
|
3066
3066
|
return
|
3067
|
-
from meerschaum.utils.sql import
|
3067
|
+
from meerschaum.utils.sql import (
|
3068
|
+
sql_item_name,
|
3069
|
+
get_table_cols_types,
|
3070
|
+
DROP_IF_EXISTS_FLAVORS,
|
3071
|
+
SINGLE_ALTER_TABLE_FLAVORS,
|
3072
|
+
)
|
3068
3073
|
from meerschaum.utils.dataframe import get_numeric_cols
|
3069
3074
|
from meerschaum.utils.dtypes import are_dtypes_equal
|
3070
3075
|
from meerschaum.utils.dtypes.sql import (
|
@@ -3308,14 +3313,19 @@ def get_alter_columns_queries(
|
|
3308
3313
|
else 'TYPE '
|
3309
3314
|
)
|
3310
3315
|
column_str = 'COLUMN' if self.flavor != 'oracle' else ''
|
3311
|
-
|
3316
|
+
query_suffix = (
|
3312
3317
|
f"\n{alter_col_prefix} {column_str} "
|
3313
3318
|
+ sql_item_name(col, self.flavor, None)
|
3314
3319
|
+ " " + type_prefix + typ + ","
|
3315
3320
|
)
|
3321
|
+
if self.flavor not in SINGLE_ALTER_TABLE_FLAVORS:
|
3322
|
+
query += query_suffix
|
3323
|
+
else:
|
3324
|
+
queries.append(query + query_suffix[:-1])
|
3325
|
+
|
3326
|
+
if self.flavor not in SINGLE_ALTER_TABLE_FLAVORS:
|
3327
|
+
queries.append(query[:-1])
|
3316
3328
|
|
3317
|
-
query = query[:-1]
|
3318
|
-
queries.append(query)
|
3319
3329
|
if self.flavor != 'duckdb':
|
3320
3330
|
return queries
|
3321
3331
|
|
@@ -6,8 +6,10 @@ This module contains SQLConnector functions for executing SQL queries.
|
|
6
6
|
"""
|
7
7
|
|
8
8
|
from __future__ import annotations
|
9
|
+
|
10
|
+
import meerschaum as mrsm
|
9
11
|
from meerschaum.utils.typing import (
|
10
|
-
Union,
|
12
|
+
Union, List, Dict, SuccessTuple, Optional, Any, Iterable, Callable,
|
11
13
|
Tuple, Hashable,
|
12
14
|
)
|
13
15
|
|
@@ -15,7 +17,7 @@ from meerschaum.utils.debug import dprint
|
|
15
17
|
from meerschaum.utils.warnings import warn
|
16
18
|
|
17
19
|
### database flavors that can use bulk insert
|
18
|
-
_bulk_flavors = {'postgresql', 'timescaledb', 'citus'}
|
20
|
+
_bulk_flavors = {'postgresql', 'timescaledb', 'citus', 'mssql'}
|
19
21
|
### flavors that do not support chunks
|
20
22
|
_disallow_chunks_flavors = ['duckdb']
|
21
23
|
_max_chunks_flavors = {'sqlite': 1000}
|
@@ -779,6 +781,7 @@ def to_sql(
|
|
779
781
|
from meerschaum.utils.warnings import error, warn
|
780
782
|
import warnings
|
781
783
|
import functools
|
784
|
+
|
782
785
|
if name is None:
|
783
786
|
error(f"Name must not be `None` to insert data into {self}.")
|
784
787
|
|
@@ -805,6 +808,7 @@ def to_sql(
|
|
805
808
|
quantize_decimal,
|
806
809
|
coerce_timezone,
|
807
810
|
encode_bytes_for_bytea,
|
811
|
+
serialize_bytes,
|
808
812
|
)
|
809
813
|
from meerschaum.utils.dtypes.sql import (
|
810
814
|
NUMERIC_PRECISION_FLAVORS,
|
@@ -821,24 +825,36 @@ def to_sql(
|
|
821
825
|
bytes_cols = get_bytes_cols(df)
|
822
826
|
numeric_cols = get_numeric_cols(df)
|
823
827
|
|
824
|
-
|
828
|
+
enable_bulk_insert = mrsm.get_config(
|
829
|
+
'system', 'connectors', 'sql', 'bulk_insert'
|
830
|
+
).get(self.flavor, False)
|
831
|
+
stats = {'target': name}
|
825
832
|
### resort to defaults if None
|
826
833
|
copied = False
|
827
|
-
|
834
|
+
use_bulk_insert = False
|
828
835
|
if method == "":
|
829
|
-
if
|
830
|
-
method =
|
831
|
-
|
836
|
+
if enable_bulk_insert:
|
837
|
+
method = (
|
838
|
+
functools.partial(mssql_insert_json, debug=debug)
|
839
|
+
if self.flavor == 'mssql'
|
840
|
+
else functools.partial(psql_insert_copy, debug=debug)
|
841
|
+
)
|
842
|
+
use_bulk_insert = True
|
832
843
|
else:
|
833
844
|
### Should resolve to 'multi' or `None`.
|
834
845
|
method = flavor_configs.get(self.flavor, {}).get('to_sql', {}).get('method', 'multi')
|
835
846
|
|
836
|
-
if bytes_cols and (
|
847
|
+
if bytes_cols and (use_bulk_insert or self.flavor == 'oracle'):
|
837
848
|
if safe_copy and not copied:
|
838
849
|
df = df.copy()
|
839
850
|
copied = True
|
851
|
+
bytes_serializer = (
|
852
|
+
functools.partial(encode_bytes_for_bytea, with_prefix=(self.flavor != 'oracle'))
|
853
|
+
if self.flavor != 'mssql'
|
854
|
+
else serialize_bytes
|
855
|
+
)
|
840
856
|
for col in bytes_cols:
|
841
|
-
df[col] = df[col].apply(
|
857
|
+
df[col] = df[col].apply(bytes_serializer)
|
842
858
|
|
843
859
|
if self.flavor in NUMERIC_AS_TEXT_FLAVORS:
|
844
860
|
if safe_copy and not copied:
|
@@ -988,7 +1004,7 @@ def to_sql(
|
|
988
1004
|
stats['duration'] = end - start
|
989
1005
|
|
990
1006
|
if debug:
|
991
|
-
print(
|
1007
|
+
print(" done.", flush=True)
|
992
1008
|
dprint(msg)
|
993
1009
|
|
994
1010
|
stats['success'] = success
|
@@ -1005,7 +1021,7 @@ def psql_insert_copy(
|
|
1005
1021
|
conn: Union[sqlalchemy.engine.Engine, sqlalchemy.engine.Connection],
|
1006
1022
|
keys: List[str],
|
1007
1023
|
data_iter: Iterable[Any],
|
1008
|
-
|
1024
|
+
debug: bool = False,
|
1009
1025
|
) -> None:
|
1010
1026
|
"""
|
1011
1027
|
Execute SQL statement inserting data for PostgreSQL.
|
@@ -1022,18 +1038,15 @@ def psql_insert_copy(
|
|
1022
1038
|
data_iter: Iterable[Any]
|
1023
1039
|
Iterable that iterates the values to be inserted
|
1024
1040
|
|
1025
|
-
schema: Optional[str], default None
|
1026
|
-
Optionally specify the schema of the table to be inserted into.
|
1027
|
-
|
1028
1041
|
Returns
|
1029
1042
|
-------
|
1030
1043
|
None
|
1031
1044
|
"""
|
1032
1045
|
import csv
|
1033
|
-
from io import StringIO
|
1034
1046
|
import json
|
1035
1047
|
|
1036
1048
|
from meerschaum.utils.sql import sql_item_name
|
1049
|
+
from meerschaum.utils.warnings import dprint
|
1037
1050
|
|
1038
1051
|
### NOTE: PostgreSQL doesn't support NUL chars in text, so they're removed from strings.
|
1039
1052
|
data_iter = (
|
@@ -1057,6 +1070,8 @@ def psql_insert_copy(
|
|
1057
1070
|
table_name = sql_item_name(table.name, 'postgresql', table.schema)
|
1058
1071
|
columns = ', '.join(f'"{k}"' for k in keys)
|
1059
1072
|
sql = f"COPY {table_name} ({columns}) FROM STDIN WITH CSV NULL '\\N'"
|
1073
|
+
if debug:
|
1074
|
+
dprint(sql)
|
1060
1075
|
|
1061
1076
|
dbapi_conn = conn.connection
|
1062
1077
|
with dbapi_conn.cursor() as cur:
|
@@ -1065,6 +1080,76 @@ def psql_insert_copy(
|
|
1065
1080
|
writer.writerows(data_iter)
|
1066
1081
|
|
1067
1082
|
|
1083
|
+
def mssql_insert_json(
|
1084
|
+
table: pandas.io.sql.SQLTable,
|
1085
|
+
conn: Union[sqlalchemy.engine.Engine, sqlalchemy.engine.Connection],
|
1086
|
+
keys: List[str],
|
1087
|
+
data_iter: Iterable[Any],
|
1088
|
+
cols_types: Optional[Dict[str, str]] = None,
|
1089
|
+
debug: bool = False,
|
1090
|
+
):
|
1091
|
+
"""
|
1092
|
+
Execute SQL statement inserting data via OPENJSON.
|
1093
|
+
|
1094
|
+
Adapted from this snippet:
|
1095
|
+
https://gist.github.com/gordthompson/1fb0f1c3f5edbf6192e596de8350f205
|
1096
|
+
|
1097
|
+
Parameters
|
1098
|
+
----------
|
1099
|
+
table: pandas.io.sql.SQLTable
|
1100
|
+
|
1101
|
+
conn: Union[sqlalchemy.engine.Engine, sqlalchemy.engine.Connection]
|
1102
|
+
|
1103
|
+
keys: List[str]
|
1104
|
+
Column names
|
1105
|
+
|
1106
|
+
data_iter: Iterable[Any]
|
1107
|
+
Iterable that iterates the values to be inserted
|
1108
|
+
|
1109
|
+
cols_types: Optional[Dict[str, str]], default None
|
1110
|
+
If provided, use these as the columns and types for the table.
|
1111
|
+
|
1112
|
+
Returns
|
1113
|
+
-------
|
1114
|
+
None
|
1115
|
+
"""
|
1116
|
+
import json
|
1117
|
+
from meerschaum.utils.sql import sql_item_name
|
1118
|
+
from meerschaum.utils.dtypes.sql import get_pd_type_from_db_type, get_db_type_from_pd_type
|
1119
|
+
from meerschaum.utils.warnings import dprint
|
1120
|
+
table_name = sql_item_name(table.name, 'mssql', table.schema)
|
1121
|
+
if not cols_types:
|
1122
|
+
pd_types = {
|
1123
|
+
str(column.name): get_pd_type_from_db_type(str(column.type))
|
1124
|
+
for column in table.table.columns
|
1125
|
+
}
|
1126
|
+
cols_types = {
|
1127
|
+
col: get_db_type_from_pd_type(typ, 'mssql')
|
1128
|
+
for col, typ in pd_types.items()
|
1129
|
+
}
|
1130
|
+
columns = ",\n ".join([f"[{k}]" for k in keys])
|
1131
|
+
json_data = [dict(zip(keys, row)) for row in data_iter]
|
1132
|
+
with_clause = ",\n ".join(
|
1133
|
+
[
|
1134
|
+
f"[{col_name}] {col_type} '$.\"{col_name}\"'"
|
1135
|
+
for col_name, col_type in cols_types.items()
|
1136
|
+
]
|
1137
|
+
)
|
1138
|
+
placeholder = "?" if conn.dialect.paramstyle == "qmark" else "%s"
|
1139
|
+
sql = (
|
1140
|
+
f"INSERT INTO {table_name} (\n {columns}\n)\n"
|
1141
|
+
f"SELECT\n {columns}\n"
|
1142
|
+
f"FROM OPENJSON({placeholder})\n"
|
1143
|
+
"WITH (\n"
|
1144
|
+
f" {with_clause}\n"
|
1145
|
+
");"
|
1146
|
+
)
|
1147
|
+
if debug:
|
1148
|
+
dprint(sql)
|
1149
|
+
|
1150
|
+
conn.exec_driver_sql(sql, (json.dumps(json_data, default=str),))
|
1151
|
+
|
1152
|
+
|
1068
1153
|
def format_sql_query_for_dask(query: str) -> 'sqlalchemy.sql.selectable.Select':
|
1069
1154
|
"""
|
1070
1155
|
Given a `SELECT` query, return a `sqlalchemy` query for Dask to use.
|
meerschaum/jobs/__init__.py
CHANGED
@@ -13,7 +13,6 @@ import pathlib
|
|
13
13
|
import json
|
14
14
|
import shutil
|
15
15
|
import signal
|
16
|
-
import sys
|
17
16
|
import time
|
18
17
|
import traceback
|
19
18
|
from functools import partial
|
@@ -262,7 +261,10 @@ class Daemon:
|
|
262
261
|
-------
|
263
262
|
Nothing — this will exit the parent process.
|
264
263
|
"""
|
265
|
-
import platform
|
264
|
+
import platform
|
265
|
+
import sys
|
266
|
+
import os
|
267
|
+
import traceback
|
266
268
|
from meerschaum.utils.warnings import warn
|
267
269
|
from meerschaum.config import get_config
|
268
270
|
daemon = attempt_import('daemon')
|
@@ -301,6 +303,7 @@ class Daemon:
|
|
301
303
|
os.environ['LINES'], os.environ['COLUMNS'] = str(int(lines)), str(int(columns))
|
302
304
|
with self._daemon_context:
|
303
305
|
sys.stdin = self.stdin_file
|
306
|
+
_ = os.environ.pop(STATIC_CONFIG['environment']['systemd_stdin_path'], None)
|
304
307
|
os.environ[STATIC_CONFIG['environment']['daemon_id']] = self.daemon_id
|
305
308
|
os.environ['PYTHONUNBUFFERED'] = '1'
|
306
309
|
|
@@ -1085,7 +1088,8 @@ class Daemon:
|
|
1085
1088
|
|
1086
1089
|
def write_pickle(self) -> SuccessTuple:
|
1087
1090
|
"""Write the pickle file for the daemon."""
|
1088
|
-
import pickle
|
1091
|
+
import pickle
|
1092
|
+
import traceback
|
1089
1093
|
try:
|
1090
1094
|
self.path.mkdir(parents=True, exist_ok=True)
|
1091
1095
|
with open(self.pickle_path, 'wb+') as pickle_file:
|
@@ -104,7 +104,10 @@ class StdinFile(io.TextIOBase):
|
|
104
104
|
if self._file_handler is not None:
|
105
105
|
self.sel.unregister(self._file_handler)
|
106
106
|
self._file_handler.close()
|
107
|
-
|
107
|
+
try:
|
108
|
+
os.close(self._fd)
|
109
|
+
except OSError:
|
110
|
+
pass
|
108
111
|
self._file_handler = None
|
109
112
|
self._fd = None
|
110
113
|
|
@@ -831,7 +831,6 @@ def pip_install(
|
|
831
831
|
|
832
832
|
"""
|
833
833
|
from meerschaum.config._paths import VIRTENV_RESOURCES_PATH
|
834
|
-
from meerschaum.config import get_config
|
835
834
|
from meerschaum.config.static import STATIC_CONFIG
|
836
835
|
from meerschaum.utils.warnings import warn
|
837
836
|
if args is None:
|
@@ -966,6 +965,10 @@ def pip_install(
|
|
966
965
|
|
967
966
|
if '--target' not in _args and '-t' not in _args and not (not use_uv_pip and _uninstall):
|
968
967
|
if venv is not None:
|
968
|
+
vtp = venv_target_path(venv, allow_nonexistent=True, debug=debug)
|
969
|
+
if not vtp.exists():
|
970
|
+
if not init_venv(venv, force=True):
|
971
|
+
vtp.mkdir(parents=True, exist_ok=True)
|
969
972
|
_args += ['--target', venv_target_path(venv, debug=debug)]
|
970
973
|
elif (
|
971
974
|
'--target' not in _args
|
meerschaum/utils/venv/_Venv.py
CHANGED
@@ -62,8 +62,13 @@ class Venv:
|
|
62
62
|
If a `meerschaum.plugins.Plugin` was provided, its dependent virtual environments
|
63
63
|
will also be activated.
|
64
64
|
"""
|
65
|
-
from meerschaum.utils.venv import active_venvs
|
65
|
+
from meerschaum.utils.venv import active_venvs, init_venv
|
66
66
|
self._kwargs['previously_active_venvs'] = copy.deepcopy(active_venvs)
|
67
|
+
try:
|
68
|
+
return self._activate(debug=(debug or self._debug), **self._kwargs)
|
69
|
+
except OSError as e:
|
70
|
+
if not init_venv(self._venv, force=True):
|
71
|
+
raise e
|
67
72
|
return self._activate(debug=(debug or self._debug), **self._kwargs)
|
68
73
|
|
69
74
|
|
@@ -176,23 +176,26 @@ def deactivate_venv(
|
|
176
176
|
if sys.path is None:
|
177
177
|
return False
|
178
178
|
|
179
|
-
target = venv_target_path(venv, allow_nonexistent=
|
179
|
+
target = venv_target_path(venv, allow_nonexistent=True, debug=debug).as_posix()
|
180
180
|
with LOCKS['sys.path']:
|
181
181
|
if target in sys.path:
|
182
|
-
|
182
|
+
try:
|
183
|
+
sys.path.remove(target)
|
184
|
+
except Exception:
|
185
|
+
pass
|
183
186
|
try:
|
184
187
|
active_venvs_order.remove(venv)
|
185
|
-
except Exception
|
188
|
+
except Exception:
|
186
189
|
pass
|
187
190
|
|
188
191
|
return True
|
189
192
|
|
190
193
|
|
191
194
|
def is_venv_active(
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
195
|
+
venv: str = 'mrsm',
|
196
|
+
color : bool = True,
|
197
|
+
debug: bool = False
|
198
|
+
) -> bool:
|
196
199
|
"""
|
197
200
|
Check if a virtual environment is active.
|
198
201
|
|
@@ -395,9 +398,13 @@ def init_venv(
|
|
395
398
|
|
396
399
|
def update_lock(active: bool):
|
397
400
|
try:
|
398
|
-
if active:
|
401
|
+
if not active:
|
402
|
+
if debug:
|
403
|
+
print(f"Releasing lock: '{lock_path}'")
|
399
404
|
lock_path.unlink()
|
400
405
|
else:
|
406
|
+
if debug:
|
407
|
+
print(f"Acquiring lock: '{lock_path}'")
|
401
408
|
lock_path.touch()
|
402
409
|
except Exception:
|
403
410
|
pass
|
@@ -406,9 +413,12 @@ def init_venv(
|
|
406
413
|
max_lock_seconds = 1.0
|
407
414
|
step_sleep_seconds = 0.1
|
408
415
|
init_venv_check_start = time.perf_counter()
|
409
|
-
while (time.perf_counter() - init_venv_check_start < max_lock_seconds):
|
416
|
+
while ((time.perf_counter() - init_venv_check_start) < max_lock_seconds):
|
410
417
|
if not lock_path.exists():
|
411
|
-
|
418
|
+
break
|
419
|
+
|
420
|
+
if debug:
|
421
|
+
print(f"Lock exists for '{venv}', sleeping...")
|
412
422
|
time.sleep(step_sleep_seconds)
|
413
423
|
update_lock(False)
|
414
424
|
|
@@ -441,10 +451,9 @@ def init_venv(
|
|
441
451
|
rename_vtp = vtp.exists() and not temp_vtp.exists()
|
442
452
|
|
443
453
|
if rename_vtp:
|
444
|
-
|
445
|
-
vtp
|
446
|
-
|
447
|
-
pass
|
454
|
+
if debug:
|
455
|
+
print(f"Moving '{vtp}' to '{temp_vtp}'...")
|
456
|
+
shutil.move(vtp, temp_vtp)
|
448
457
|
|
449
458
|
wait_for_lock()
|
450
459
|
update_lock(True)
|
@@ -491,7 +500,9 @@ def init_venv(
|
|
491
500
|
+ "Please install `virtualenv` via pip then restart Meerschaum."
|
492
501
|
)
|
493
502
|
if rename_vtp and temp_vtp.exists():
|
494
|
-
|
503
|
+
if debug:
|
504
|
+
print(f"Moving '{temp_vtp}' back to '{vtp}'...")
|
505
|
+
shutil.move(temp_vtp, vtp)
|
495
506
|
update_lock(False)
|
496
507
|
return False
|
497
508
|
|
@@ -530,7 +541,7 @@ def init_venv(
|
|
530
541
|
import traceback
|
531
542
|
traceback.print_exc()
|
532
543
|
if rename_vtp and temp_vtp.exists():
|
533
|
-
|
544
|
+
shutil.move(temp_vtp, vtp)
|
534
545
|
update_lock(False)
|
535
546
|
return False
|
536
547
|
if verify:
|
@@ -538,7 +549,9 @@ def init_venv(
|
|
538
549
|
verified_venvs.add(venv)
|
539
550
|
|
540
551
|
if rename_vtp and temp_vtp.exists():
|
541
|
-
|
552
|
+
if debug:
|
553
|
+
print(f"Cleanup: move '{temp_vtp}' back to '{vtp}'.")
|
554
|
+
shutil.move(temp_vtp, vtp)
|
542
555
|
|
543
556
|
update_lock(False)
|
544
557
|
return True
|
@@ -653,10 +666,10 @@ def venv_exists(venv: Union[str, None], debug: bool = False) -> bool:
|
|
653
666
|
|
654
667
|
|
655
668
|
def venv_target_path(
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
669
|
+
venv: Union[str, None],
|
670
|
+
allow_nonexistent: bool = False,
|
671
|
+
debug: bool = False,
|
672
|
+
) -> 'pathlib.Path':
|
660
673
|
"""
|
661
674
|
Return a virtual environment's site-package path.
|
662
675
|
|
@@ -673,7 +686,11 @@ def venv_target_path(
|
|
673
686
|
The `pathlib.Path` object for the virtual environment's path.
|
674
687
|
|
675
688
|
"""
|
676
|
-
import os
|
689
|
+
import os
|
690
|
+
import sys
|
691
|
+
import platform
|
692
|
+
import pathlib
|
693
|
+
import site
|
677
694
|
from meerschaum.config._paths import VIRTENV_RESOURCES_PATH
|
678
695
|
from meerschaum.config.static import STATIC_CONFIG
|
679
696
|
|
@@ -42,9 +42,9 @@ meerschaum/actions/restart.py,sha256=6ffp3-X9eTEgunVSdD41HnOwqp71yjuSAmXJ5j39ONI
|
|
42
42
|
meerschaum/actions/setup.py,sha256=KkAGWcgwzl_L6A19fTmTX1KtBjW2FwD8QenLjPy0mQQ,3205
|
43
43
|
meerschaum/actions/sh.py,sha256=hSkGNTVqP5dNjhJ64zy3V3VCFPTKnDlH3PxdKdxtkGQ,1990
|
44
44
|
meerschaum/actions/show.py,sha256=T8Ol1o-762cI9rlUzd-8svvwgT4slYXYfOPQETh9Koo,28446
|
45
|
-
meerschaum/actions/sql.py,sha256=
|
45
|
+
meerschaum/actions/sql.py,sha256=zG-KydYR654RHaF-O4Id3ACCDWeogk2B1R-OFLwFbG0,4515
|
46
46
|
meerschaum/actions/stack.py,sha256=ZwrCTGJ0x3jjZkRieWcvqasQHYCqNtB1HYvTX-r3Z3g,5996
|
47
|
-
meerschaum/actions/start.py,sha256=
|
47
|
+
meerschaum/actions/start.py,sha256=NtdVzeB00PQBnDSUSu8ypHmMrZT8_Idmw5BfVZ--Zic,21296
|
48
48
|
meerschaum/actions/stop.py,sha256=5fdUw70YN-yuUWrC-NhA88cxr9FZ5NbssbQ8xXO8nFU,4632
|
49
49
|
meerschaum/actions/sync.py,sha256=QGhf0ZyrNaplPL6TkwHO9VQLEu_Gemmid93vdaovXoo,17153
|
50
50
|
meerschaum/actions/tag.py,sha256=SJf5qFW0ccLXjqlTdkK_0MCcrCMdg6xhYrhKdco0hdA,3053
|
@@ -132,7 +132,7 @@ meerschaum/api/routes/_webterm.py,sha256=MenDvWXnZ8CWEmryB46pKohMf0PN6o1xJGZ3LFj
|
|
132
132
|
meerschaum/api/tables/__init__.py,sha256=e2aNC0CdlWICTUMx1i9RauF8Pm426J0RZJbsJWv4SWo,482
|
133
133
|
meerschaum/config/__init__.py,sha256=5ZBq71P9t3nb74r5CGvMfNuauPscfegBX-nkaAUi5C4,11541
|
134
134
|
meerschaum/config/_dash.py,sha256=BJHl4xMrQB-YHUEU7ldEW8q_nOPoIRSOqLrfGElc6Dw,187
|
135
|
-
meerschaum/config/_default.py,sha256=
|
135
|
+
meerschaum/config/_default.py,sha256=IDRo8nLWija_cawiqeS6cPwZ9deDF9179m_rwGntNLA,5831
|
136
136
|
meerschaum/config/_edit.py,sha256=M9yX_SDD24gV5kWITZpy7p9AWTizJsIAGWAs3WZx-Ws,9087
|
137
137
|
meerschaum/config/_environment.py,sha256=Vv4DLDfc2vKLbCLsMvkQDj77K4kEvHKEBmUBo-wCrgo,4419
|
138
138
|
meerschaum/config/_formatting.py,sha256=OMuqS1EWOsj_34wSs2tOqGIWci3bTMIZ5l-uelZgsIM,6672
|
@@ -143,7 +143,7 @@ meerschaum/config/_preprocess.py,sha256=-AEA8m_--KivZwTQ1sWN6LTn5sio_fUr2XZ51BO6
|
|
143
143
|
meerschaum/config/_read_config.py,sha256=RLC3HHi_1ndj7ITVDKLD9_uULY3caGRwSz3ATYE-ixA,15014
|
144
144
|
meerschaum/config/_shell.py,sha256=46_m49Txc5q1rGfCgO49ca48BODx45DQJi8D0zz1R18,4245
|
145
145
|
meerschaum/config/_sync.py,sha256=jHcWRkxd82_BgX8Xo8agsWvf7BSbv3qHLWmYl6ehp_0,4242
|
146
|
-
meerschaum/config/_version.py,sha256=
|
146
|
+
meerschaum/config/_version.py,sha256=FtGr91JvNFrz0tCWU-8xhZY04Aon0uXjcSuAPXv1SUI,71
|
147
147
|
meerschaum/config/paths.py,sha256=JjibeGN3YAdSNceRwsd42aNmeUrIgM6ndzC8qZAmNI0,621
|
148
148
|
meerschaum/config/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
149
149
|
meerschaum/config/stack/__init__.py,sha256=2UukC0Lmk-aVL1o1qXzumqmuIrw3vu9fD7iCuz4XD4I,10544
|
@@ -172,13 +172,13 @@ meerschaum/connectors/plugin/PluginConnector.py,sha256=aQ1QaB7MordCFimZqoGLb0R12
|
|
172
172
|
meerschaum/connectors/plugin/__init__.py,sha256=pwF7TGY4WNz2_HaVdmK4rPQ9ZwTOEuPHgzOqsGcoXJw,198
|
173
173
|
meerschaum/connectors/sql/_SQLConnector.py,sha256=g9SFK30CZp7CTJI-SdpOanL1NQUBFQeUng7FSGacJA4,11985
|
174
174
|
meerschaum/connectors/sql/__init__.py,sha256=3cqYiDkVasn7zWdtOTAZbT4bo95AuvGOmDD2TkaAxtw,205
|
175
|
-
meerschaum/connectors/sql/_cli.py,sha256=
|
176
|
-
meerschaum/connectors/sql/_create_engine.py,sha256=
|
175
|
+
meerschaum/connectors/sql/_cli.py,sha256=VqAHkdXC0HVXuHaZik2q-cTVmIsuS4DWMcPMJPP_g-Q,4514
|
176
|
+
meerschaum/connectors/sql/_create_engine.py,sha256=RzJz4Qc43P4JS6tkgVvAhbdjEejIepWbxymIfVZ44Nk,10555
|
177
177
|
meerschaum/connectors/sql/_fetch.py,sha256=GOU1JnPOBgaI3dDr0JdAmfTMPLIMM0EFHrsqDgDIO74,14070
|
178
178
|
meerschaum/connectors/sql/_instance.py,sha256=mmZnodccuCqmZN-UnznnFZ7JodxtT47kwjDDaDKgwUg,6274
|
179
|
-
meerschaum/connectors/sql/_pipes.py,sha256=
|
179
|
+
meerschaum/connectors/sql/_pipes.py,sha256=n0tHoVnBmno08qqO5qaFuSlfIW96_VVm8T1k5ZRdPQw,121592
|
180
180
|
meerschaum/connectors/sql/_plugins.py,sha256=wbxcNxqTtjfDsxPvdVGTllasYf6NHHzODaQ72hEUSBQ,8135
|
181
|
-
meerschaum/connectors/sql/_sql.py,sha256=
|
181
|
+
meerschaum/connectors/sql/_sql.py,sha256=Q4MKuUlqrgXuYCbpCtoQlvqOvASDQ7BkkLLSYPLh_JE,41052
|
182
182
|
meerschaum/connectors/sql/_uri.py,sha256=0BrhQtqQdzg9mR04gWBZINs_BbPFtSlTECXT_TCUwik,3460
|
183
183
|
meerschaum/connectors/sql/_users.py,sha256=FJjYeJGhr-TDHziNc6p_5mupGRtGjezKPIYgHFEVSnY,9956
|
184
184
|
meerschaum/connectors/sql/tools.py,sha256=jz8huOaRCwGlYdtGfAqAh7SoK8uydYBrasKQba9FT38,187
|
@@ -212,7 +212,7 @@ meerschaum/core/User/_User.py,sha256=qbI0GIkr3G0PI4d9S49uatbJQ2kH_-z5-GoVJ0fuEtA
|
|
212
212
|
meerschaum/core/User/__init__.py,sha256=9qNy-Gobui4x6GiaE8U7-WOggsdniOM3_wegLN3SVKs,988
|
213
213
|
meerschaum/jobs/_Executor.py,sha256=qM62BhFTM4tyJ7p90KOM0y3qyeRY9k3ZV_aTDJMHnO8,1682
|
214
214
|
meerschaum/jobs/_Job.py,sha256=wRsmrQ1bm898BxXELbHTltKYBj0bK0GmegE8zeL0FG8,32161
|
215
|
-
meerschaum/jobs/__init__.py,sha256=
|
215
|
+
meerschaum/jobs/__init__.py,sha256=YjwB6t8HCT593ckrOlImgk0kLX-1NgAYzNXVwS-uvyY,12173
|
216
216
|
meerschaum/jobs/systemd.py,sha256=Rq-tsDPslG17ZhpKMrVJ5r8Z0IPr6DEc9APObfIoXCg,24614
|
217
217
|
meerschaum/plugins/_Plugin.py,sha256=bIo4HX8TTWIcwIHROwMt4VK6OoEUhY_3Qc8q-2dp-ZA,33895
|
218
218
|
meerschaum/plugins/__init__.py,sha256=6krcqaMKyzuVqesXMqEL0XEy2SJQ4xfNt2-oI_fJ6v0,26278
|
@@ -233,10 +233,10 @@ meerschaum/utils/threading.py,sha256=awjbVL_QR6G-o_9Qk85utac9cSdqkiC8tQSdERCdrG8
|
|
233
233
|
meerschaum/utils/typing.py,sha256=U3MC347sh1umpa3Xr1k71eADyDmk4LB6TnVCpq8dVzI,2830
|
234
234
|
meerschaum/utils/warnings.py,sha256=n-phr3BftNNgyPnvnXC_VMSjtCvjiCZ-ewmVfcROhkc,6611
|
235
235
|
meerschaum/utils/yaml.py,sha256=PoC1du0pn2hLwTHwL-zuOf_EBWZSbCGOz-P-AZ4BWN0,3901
|
236
|
-
meerschaum/utils/daemon/Daemon.py,sha256=
|
236
|
+
meerschaum/utils/daemon/Daemon.py,sha256=zxU15r7XJCTU5r5IWdiH9GQEenUFSnV439f0Vq1EzgY,42760
|
237
237
|
meerschaum/utils/daemon/FileDescriptorInterceptor.py,sha256=MJKMO0Syf3d8yWUs6xXcQzg8Ptsuvh2aCRRoglOjusA,5257
|
238
238
|
meerschaum/utils/daemon/RotatingFile.py,sha256=ePm_svjwyFDWh6V1k-bp1RHXCSWlyxDtlFu4SU4XvPU,24369
|
239
|
-
meerschaum/utils/daemon/StdinFile.py,sha256=
|
239
|
+
meerschaum/utils/daemon/StdinFile.py,sha256=qdZ8E_RSOkURypwnS50mWeyWyRig1bAY9tKWMTVKajc,3307
|
240
240
|
meerschaum/utils/daemon/__init__.py,sha256=o9jWb4lRTIyny4EPt7fPXFgV_vIf1mUofsTwoE1ZecA,8751
|
241
241
|
meerschaum/utils/daemon/_names.py,sha256=d2ZwTxBoTAqXZkCfZ5LuX2XrkQmLNUq1OTlUqfoH5dA,4515
|
242
242
|
meerschaum/utils/dtypes/__init__.py,sha256=c6DoYyCbWvMdRapBRKP5UJYLRUWtkTIlC_8HRzXFh2s,12166
|
@@ -246,16 +246,16 @@ meerschaum/utils/formatting/_jobs.py,sha256=izsqPJhTtUkXUUtWnbXtReYsUYwulXtci3pB
|
|
246
246
|
meerschaum/utils/formatting/_pipes.py,sha256=OISJmmFiilaDbZxkiXck_g39MnnTfk_fJJyJ-YInvXA,19559
|
247
247
|
meerschaum/utils/formatting/_pprint.py,sha256=tgrT3FyGyu5CWJYysqK3kX1xdZYorlbOk9fcU_vt9Qg,3096
|
248
248
|
meerschaum/utils/formatting/_shell.py,sha256=XH7VFLteNv7NGtWhJl7FdIGt80sKeTiDoJokGSDAwBM,3761
|
249
|
-
meerschaum/utils/packages/__init__.py,sha256=
|
249
|
+
meerschaum/utils/packages/__init__.py,sha256=vg1C9dpj1MLOWgvNGrKkqLRe4Z9hUnNdQDOCvReCBh4,64392
|
250
250
|
meerschaum/utils/packages/_packages.py,sha256=ykannoLv2Fm4iwZwiIlNAGZvt654cMJhjXr1VJPoEDo,8867
|
251
251
|
meerschaum/utils/packages/lazy_loader.py,sha256=VHnph3VozH29R4JnSSBfwtA5WKZYZQFT_GeQSShCnuc,2540
|
252
|
-
meerschaum/utils/venv/_Venv.py,sha256=
|
253
|
-
meerschaum/utils/venv/__init__.py,sha256=
|
254
|
-
meerschaum-2.7.
|
255
|
-
meerschaum-2.7.
|
256
|
-
meerschaum-2.7.
|
257
|
-
meerschaum-2.7.
|
258
|
-
meerschaum-2.7.
|
259
|
-
meerschaum-2.7.
|
260
|
-
meerschaum-2.7.
|
261
|
-
meerschaum-2.7.
|
252
|
+
meerschaum/utils/venv/_Venv.py,sha256=gc1TCeAj-kTZbQFAT9xl1bi4HXFV5ApT0dPOJfxwr78,3748
|
253
|
+
meerschaum/utils/venv/__init__.py,sha256=wqjp0ocIkp6nsHYLUObXIhfYY5CjX-JnS6psm783ga0,26755
|
254
|
+
meerschaum-2.7.5.dist-info/LICENSE,sha256=jG2zQEdRNt88EgHUWPpXVWmOrOduUQRx7MnYV9YIPaw,11359
|
255
|
+
meerschaum-2.7.5.dist-info/METADATA,sha256=kQOkmZPuhuo-Ee1b_2JlzUnmfGYOZOBBUWs3pHZ_g1M,24224
|
256
|
+
meerschaum-2.7.5.dist-info/NOTICE,sha256=OTA9Fcthjf5BRvWDDIcBC_xfLpeDV-RPZh3M-HQBRtQ,114
|
257
|
+
meerschaum-2.7.5.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
258
|
+
meerschaum-2.7.5.dist-info/entry_points.txt,sha256=5YBVzibw-0rNA_1VjB16z5GABsOGf-CDhW4yqH8C7Gc,88
|
259
|
+
meerschaum-2.7.5.dist-info/top_level.txt,sha256=bNoSiDj0El6buocix-FRoAtJOeq1qOF5rRm2u9i7Q6A,11
|
260
|
+
meerschaum-2.7.5.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
261
|
+
meerschaum-2.7.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|