meerschaum 2.7.4__py3-none-any.whl → 2.7.5__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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, import_pandas
128
+ from meerschaum.utils.packages import attempt_import
129
129
  from meerschaum.utils.formatting import print_tuple, pprint
130
- sqlalchemy_engine_result = attempt_import('sqlalchemy.engine.result')
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
+ ]
@@ -68,6 +68,12 @@ default_system_config = {
68
68
  'pandas': 'pandas',
69
69
  },
70
70
  'sql': {
71
+ 'bulk_insert': {
72
+ 'postgresql': True,
73
+ 'citus': True,
74
+ 'timescaledb': True,
75
+ 'mssql': True,
76
+ },
71
77
  'instance': {
72
78
  'stale_temporary_tables_minutes': 1440,
73
79
  },
@@ -2,4 +2,4 @@
2
2
  Specify the Meerschaum release version.
3
3
  """
4
4
 
5
- __version__ = "2.7.4"
5
+ __version__ = "2.7.5"
@@ -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
- self,
36
- debug: bool = False,
37
- ) -> SuccessTuple:
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
- env[f'MRSM_SQL_{self.label.upper()}'] = json.dumps(self.meta)
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
- self,
62
- debug: bool = False
63
- ) -> SuccessTuple:
68
+ self,
69
+ debug: bool = False
70
+ ) -> SuccessTuple:
64
71
  """Launch an interactive CLI for the SQLConnector's flavor."""
65
- from meerschaum.utils.packages import venv_exec, attempt_import
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}'."
@@ -61,6 +61,7 @@ flavor_configs = {
61
61
  'engine': 'mssql+pyodbc',
62
62
  'create_engine': {
63
63
  'fast_executemany': True,
64
+ 'use_insertmanyvalues': False,
64
65
  'isolation_level': 'AUTOCOMMIT',
65
66
  'use_setinputsizes': False,
66
67
  'pool_pre_ping': True,
@@ -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 sql_item_name, DROP_IF_EXISTS_FLAVORS, get_table_cols_types
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
- query += (
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, Mapping, List, Dict, SuccessTuple, Optional, Any, Iterable, Callable,
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
- stats = {'target': name,}
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
- use_psql_copy = False
834
+ use_bulk_insert = False
828
835
  if method == "":
829
- if self.flavor in _bulk_flavors:
830
- method = functools.partial(psql_insert_copy, schema=self.schema)
831
- use_psql_copy = True
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 (use_psql_copy or self.flavor == 'oracle'):
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(encode_bytes_for_bytea, with_prefix=(self.flavor != 'oracle'))
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(f" done.", flush=True)
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
- schema: Optional[str] = None,
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.
@@ -261,7 +261,10 @@ class Daemon:
261
261
  -------
262
262
  Nothing — this will exit the parent process.
263
263
  """
264
- import platform, sys, os, traceback
264
+ import platform
265
+ import sys
266
+ import os
267
+ import traceback
265
268
  from meerschaum.utils.warnings import warn
266
269
  from meerschaum.config import get_config
267
270
  daemon = attempt_import('daemon')
@@ -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, traceback
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:
@@ -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
@@ -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=force, debug=debug).as_posix()
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
- sys.path.remove(target)
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 as e:
188
+ except Exception:
186
189
  pass
187
190
 
188
191
  return True
189
192
 
190
193
 
191
194
  def is_venv_active(
192
- venv: str = 'mrsm',
193
- color : bool = True,
194
- debug: bool = False
195
- ) -> bool:
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
 
@@ -410,7 +413,7 @@ def init_venv(
410
413
  max_lock_seconds = 1.0
411
414
  step_sleep_seconds = 0.1
412
415
  init_venv_check_start = time.perf_counter()
413
- while (time.perf_counter() - init_venv_check_start < max_lock_seconds):
416
+ while ((time.perf_counter() - init_venv_check_start) < max_lock_seconds):
414
417
  if not lock_path.exists():
415
418
  break
416
419
 
@@ -663,10 +666,10 @@ def venv_exists(venv: Union[str, None], debug: bool = False) -> bool:
663
666
 
664
667
 
665
668
  def venv_target_path(
666
- venv: Union[str, None],
667
- allow_nonexistent: bool = False,
668
- debug: bool = False,
669
- ) -> 'pathlib.Path':
669
+ venv: Union[str, None],
670
+ allow_nonexistent: bool = False,
671
+ debug: bool = False,
672
+ ) -> 'pathlib.Path':
670
673
  """
671
674
  Return a virtual environment's site-package path.
672
675
 
@@ -683,7 +686,11 @@ def venv_target_path(
683
686
  The `pathlib.Path` object for the virtual environment's path.
684
687
 
685
688
  """
686
- import os, sys, platform, pathlib, site
689
+ import os
690
+ import sys
691
+ import platform
692
+ import pathlib
693
+ import site
687
694
  from meerschaum.config._paths import VIRTENV_RESOURCES_PATH
688
695
  from meerschaum.config.static import STATIC_CONFIG
689
696
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: meerschaum
3
- Version: 2.7.4
3
+ Version: 2.7.5
4
4
  Summary: Sync Time-Series Pipes with Meerschaum
5
5
  Home-page: https://meerschaum.io
6
6
  Author: Bennett Meares
@@ -42,7 +42,7 @@ 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=vAsxbSl-Hkw3wfrM1BLnKex_kJrZwIJICAXysprQGWM,4220
45
+ meerschaum/actions/sql.py,sha256=zG-KydYR654RHaF-O4Id3ACCDWeogk2B1R-OFLwFbG0,4515
46
46
  meerschaum/actions/stack.py,sha256=ZwrCTGJ0x3jjZkRieWcvqasQHYCqNtB1HYvTX-r3Z3g,5996
47
47
  meerschaum/actions/start.py,sha256=NtdVzeB00PQBnDSUSu8ypHmMrZT8_Idmw5BfVZ--Zic,21296
48
48
  meerschaum/actions/stop.py,sha256=5fdUw70YN-yuUWrC-NhA88cxr9FZ5NbssbQ8xXO8nFU,4632
@@ -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=3HhlLLceFbf7zn3sciIr0DWGynuHpzRmkmXeTyT9J9s,5652
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=MXSVkU-_rIMkbFaFaLStOfNg5rNqfnzfD42W6YOfi6s,71
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=1SgnWeMIAihoxp4FzbNrcq1npXf0dSOQnCntpU9hUXA,4405
176
- meerschaum/connectors/sql/_create_engine.py,sha256=MqgFhtWUMSgkx6Qu6Q6Ny3jIz-GWix_Eawko59RLm1o,10512
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=EhuCZeGDTeywHvcbIlkipxouSGqgq_blU1z6-jrWLTY,121316
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=ktXYiI0EpP7syRaW-PCvB14oaMFtWlfCVOjKCUNYBu8,38509
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
@@ -233,7 +233,7 @@ 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=PfFu_yba5d9k8GW3mGmJRilenyNNoA9DEG2TiiFfyMI,42704
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
239
  meerschaum/utils/daemon/StdinFile.py,sha256=qdZ8E_RSOkURypwnS50mWeyWyRig1bAY9tKWMTVKajc,3307
@@ -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=Op93VJkAX3OL4H-js_p3dAaa_PT82jvjCna27aHOsUk,64199
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=QsnDGEE_YBqXIq53NTWi2TANA1FbkqJBl_xQi9jQP_U,3537
253
- meerschaum/utils/venv/__init__.py,sha256=m8tgZvk2VxYd6OHfiJlE1tpHo9b7hH69y1UmHeY6ncM,26679
254
- meerschaum-2.7.4.dist-info/LICENSE,sha256=jG2zQEdRNt88EgHUWPpXVWmOrOduUQRx7MnYV9YIPaw,11359
255
- meerschaum-2.7.4.dist-info/METADATA,sha256=tHOCaQB1p7j8P6denDGdRHY4fhxNcTkqkzqBBo_r9SU,24224
256
- meerschaum-2.7.4.dist-info/NOTICE,sha256=OTA9Fcthjf5BRvWDDIcBC_xfLpeDV-RPZh3M-HQBRtQ,114
257
- meerschaum-2.7.4.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
258
- meerschaum-2.7.4.dist-info/entry_points.txt,sha256=5YBVzibw-0rNA_1VjB16z5GABsOGf-CDhW4yqH8C7Gc,88
259
- meerschaum-2.7.4.dist-info/top_level.txt,sha256=bNoSiDj0El6buocix-FRoAtJOeq1qOF5rRm2u9i7Q6A,11
260
- meerschaum-2.7.4.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
261
- meerschaum-2.7.4.dist-info/RECORD,,
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,,