meerschaum 2.4.13__py3-none-any.whl → 2.5.0__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/upgrade.py +3 -2
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/sql/_create_engine.py +8 -3
- meerschaum/connectors/sql/_fetch.py +2 -2
- meerschaum/connectors/sql/_instance.py +3 -3
- meerschaum/connectors/sql/_pipes.py +18 -13
- meerschaum/connectors/sql/_sql.py +59 -50
- meerschaum/core/Pipe/__init__.py +23 -1
- meerschaum/core/Pipe/_attributes.py +96 -14
- meerschaum/utils/dataframe.py +17 -5
- meerschaum/utils/packages/__init__.py +40 -22
- meerschaum/utils/packages/_packages.py +24 -8
- meerschaum/utils/schedule.py +9 -5
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/METADATA +9 -13
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/RECORD +21 -21
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/LICENSE +0 -0
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/NOTICE +0 -0
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/WHEEL +0 -0
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/top_level.txt +0 -0
- {meerschaum-2.4.13.dist-info → meerschaum-2.5.0.dist-info}/zip-safe +0 -0
meerschaum/actions/upgrade.py
CHANGED
@@ -109,6 +109,7 @@ def _upgrade_meerschaum(
|
|
109
109
|
class NoVenv:
|
110
110
|
pass
|
111
111
|
|
112
|
+
|
112
113
|
def _upgrade_packages(
|
113
114
|
action: Optional[List[str]] = None,
|
114
115
|
venv: Union[str, None, NoVenv] = NoVenv,
|
@@ -121,7 +122,7 @@ def _upgrade_packages(
|
|
121
122
|
"""
|
122
123
|
Upgrade and install dependencies.
|
123
124
|
If provided, upgrade only a dependency group, otherwise default to `full`.
|
124
|
-
|
125
|
+
|
125
126
|
Examples:
|
126
127
|
upgrade packages
|
127
128
|
upgrade packages full
|
@@ -160,7 +161,7 @@ def _upgrade_packages(
|
|
160
161
|
to_install = [
|
161
162
|
install_name
|
162
163
|
for install_name in to_install
|
163
|
-
if install_name not in prereleases_to_install
|
164
|
+
if (install_name not in prereleases_to_install) or group == '_internal'
|
164
165
|
]
|
165
166
|
|
166
167
|
success, msg = False, f"Nothing installed."
|
meerschaum/config/_version.py
CHANGED
@@ -63,6 +63,8 @@ flavor_configs = {
|
|
63
63
|
'fast_executemany': True,
|
64
64
|
'isolation_level': 'AUTOCOMMIT',
|
65
65
|
'use_setinputsizes': False,
|
66
|
+
'pool_pre_ping': True,
|
67
|
+
'ignore_no_transaction_on_rollback': True,
|
66
68
|
},
|
67
69
|
'omit_create_engine': {'method',},
|
68
70
|
'to_sql': {
|
@@ -189,15 +191,18 @@ def create_engine(
|
|
189
191
|
### Install and patch required drivers.
|
190
192
|
if self.flavor in install_flavor_drivers:
|
191
193
|
attempt_import(*install_flavor_drivers[self.flavor], debug=debug, lazy=False, warn=False)
|
194
|
+
if self.flavor == 'mssql':
|
195
|
+
pyodbc = attempt_import('pyodbc', debug=debug, lazy=False, warn=False)
|
196
|
+
pyodbc.pooling = False
|
192
197
|
if self.flavor in require_patching_flavors:
|
193
198
|
from meerschaum.utils.packages import determine_version, _monkey_patch_get_distribution
|
194
199
|
import pathlib
|
195
200
|
for install_name, import_name in require_patching_flavors[self.flavor]:
|
196
201
|
pkg = attempt_import(
|
197
202
|
import_name,
|
198
|
-
debug
|
199
|
-
lazy
|
200
|
-
warn
|
203
|
+
debug=debug,
|
204
|
+
lazy=False,
|
205
|
+
warn=False
|
201
206
|
)
|
202
207
|
_monkey_patch_get_distribution(
|
203
208
|
install_name, determine_version(pathlib.Path(pkg.__file__), venv='mrsm')
|
@@ -31,7 +31,7 @@ def fetch(
|
|
31
31
|
----------
|
32
32
|
pipe: mrsm.Pipe
|
33
33
|
The pipe object which contains the `fetch` metadata.
|
34
|
-
|
34
|
+
|
35
35
|
- pipe.columns['datetime']: str
|
36
36
|
- Name of the datetime column for the remote table.
|
37
37
|
- pipe.parameters['fetch']: Dict[str, Any]
|
@@ -196,7 +196,7 @@ def get_pipe_metadef(
|
|
196
196
|
dateadd_str(
|
197
197
|
flavor=self.flavor,
|
198
198
|
datepart='minute',
|
199
|
-
number=((-1 * btm) if apply_backtrack else 0),
|
199
|
+
number=((-1 * btm) if apply_backtrack else 0),
|
200
200
|
begin=begin,
|
201
201
|
)
|
202
202
|
if begin
|
@@ -88,9 +88,9 @@ def _drop_temporary_tables(self, debug: bool = False) -> SuccessTuple:
|
|
88
88
|
from meerschaum.connectors.sql.tables import get_tables
|
89
89
|
sqlalchemy = mrsm.attempt_import('sqlalchemy')
|
90
90
|
temp_tables_table = get_tables(
|
91
|
-
mrsm_instance
|
92
|
-
create
|
93
|
-
debug
|
91
|
+
mrsm_instance=self,
|
92
|
+
create=False,
|
93
|
+
debug=debug,
|
94
94
|
)['temp_tables']
|
95
95
|
query = (
|
96
96
|
sqlalchemy.select(temp_tables_table.c.table)
|
@@ -384,7 +384,7 @@ def get_create_index_queries(
|
|
384
384
|
|
385
385
|
Returns
|
386
386
|
-------
|
387
|
-
A dictionary of
|
387
|
+
A dictionary of index names mapping to lists of queries.
|
388
388
|
"""
|
389
389
|
### NOTE: Due to recent breaking changes in DuckDB, indices don't behave properly.
|
390
390
|
if self.flavor == 'duckdb':
|
@@ -400,7 +400,8 @@ def get_create_index_queries(
|
|
400
400
|
index_queries = {}
|
401
401
|
|
402
402
|
upsert = pipe.parameters.get('upsert', False) and (self.flavor + '-upsert') in update_queries
|
403
|
-
|
403
|
+
index_names = pipe.get_indices()
|
404
|
+
indices = pipe.indices
|
404
405
|
|
405
406
|
_datetime = pipe.get_columns('datetime', error=False)
|
406
407
|
_datetime_type = pipe.dtypes.get(_datetime, 'datetime64[ns]')
|
@@ -409,8 +410,8 @@ def get_create_index_queries(
|
|
409
410
|
if _datetime is not None else None
|
410
411
|
)
|
411
412
|
_datetime_index_name = (
|
412
|
-
sql_item_name(
|
413
|
-
if
|
413
|
+
sql_item_name(index_names['datetime'], self.flavor, None)
|
414
|
+
if index_names.get('datetime', None)
|
414
415
|
else None
|
415
416
|
)
|
416
417
|
_id = pipe.get_columns('id', error=False)
|
@@ -421,8 +422,8 @@ def get_create_index_queries(
|
|
421
422
|
)
|
422
423
|
|
423
424
|
_id_index_name = (
|
424
|
-
sql_item_name(
|
425
|
-
if
|
425
|
+
sql_item_name(index_names['id'], self.flavor, None)
|
426
|
+
if index_names.get('id', None)
|
426
427
|
else None
|
427
428
|
)
|
428
429
|
_pipe_name = sql_item_name(pipe.target, self.flavor, self.get_pipe_schema(pipe))
|
@@ -491,18 +492,22 @@ def get_create_index_queries(
|
|
491
492
|
if id_query is not None:
|
492
493
|
index_queries[_id] = id_query if isinstance(id_query, list) else [id_query]
|
493
494
|
|
494
|
-
|
495
495
|
### Create indices for other labels in `pipe.columns`.
|
496
|
-
|
496
|
+
other_index_names = {
|
497
497
|
ix_key: ix_unquoted
|
498
|
-
for ix_key, ix_unquoted in
|
498
|
+
for ix_key, ix_unquoted in index_names.items()
|
499
499
|
if ix_key not in ('datetime', 'id')
|
500
500
|
}
|
501
|
-
for ix_key, ix_unquoted in
|
501
|
+
for ix_key, ix_unquoted in other_index_names.items():
|
502
502
|
ix_name = sql_item_name(ix_unquoted, self.flavor, None)
|
503
|
-
|
504
|
-
|
505
|
-
|
503
|
+
cols = indices[ix_key]
|
504
|
+
if not isinstance(cols, (list, tuple)):
|
505
|
+
cols = [cols]
|
506
|
+
cols_names = [sql_item_name(col, self.flavor, None) for col in cols if col]
|
507
|
+
if not cols_names:
|
508
|
+
continue
|
509
|
+
cols_names_str = ", ".join(cols_names)
|
510
|
+
index_queries[ix_key] = [f"CREATE INDEX {ix_name} ON {_pipe_name} ({cols_names_str})"]
|
506
511
|
|
507
512
|
existing_cols_types = pipe.get_columns_types(debug=debug)
|
508
513
|
indices_cols_str = ', '.join(
|
@@ -17,8 +17,9 @@ from meerschaum.utils.warnings import warn
|
|
17
17
|
### database flavors that can use bulk insert
|
18
18
|
_bulk_flavors = {'postgresql', 'timescaledb', 'citus'}
|
19
19
|
### flavors that do not support chunks
|
20
|
-
_disallow_chunks_flavors =
|
20
|
+
_disallow_chunks_flavors = ['duckdb']
|
21
21
|
_max_chunks_flavors = {'sqlite': 1000,}
|
22
|
+
SKIP_READ_TRANSACTION_FLAVORS: list[str] = ['mssql']
|
22
23
|
|
23
24
|
|
24
25
|
def read(
|
@@ -97,7 +98,7 @@ def read(
|
|
97
98
|
Defaults to `SQLConnector.schema`.
|
98
99
|
|
99
100
|
as_chunks: bool, default False
|
100
|
-
If `True`, return a list of DataFrames.
|
101
|
+
If `True`, return a list of DataFrames.
|
101
102
|
Otherwise return a single DataFrame.
|
102
103
|
|
103
104
|
as_iterator: bool, default False
|
@@ -127,7 +128,6 @@ def read(
|
|
127
128
|
from meerschaum.utils.pool import get_pool
|
128
129
|
from meerschaum.utils.dataframe import chunksize_to_npartitions, get_numeric_cols
|
129
130
|
import warnings
|
130
|
-
import inspect
|
131
131
|
import traceback
|
132
132
|
from decimal import Decimal
|
133
133
|
pd = import_pandas()
|
@@ -140,6 +140,7 @@ def read(
|
|
140
140
|
chunksize = None
|
141
141
|
schema = schema or self.schema
|
142
142
|
|
143
|
+
pool = get_pool(workers=workers)
|
143
144
|
sqlalchemy = attempt_import("sqlalchemy")
|
144
145
|
default_chunksize = self._sys_config.get('chunksize', None)
|
145
146
|
chunksize = chunksize if chunksize != -1 else default_chunksize
|
@@ -157,7 +158,7 @@ def read(
|
|
157
158
|
f"The specified chunksize of {chunksize} exceeds the maximum of "
|
158
159
|
+ f"{_max_chunks_flavors[self.flavor]} for flavor '{self.flavor}'.\n"
|
159
160
|
+ f" Falling back to a chunksize of {_max_chunks_flavors[self.flavor]}.",
|
160
|
-
stacklevel
|
161
|
+
stacklevel=3,
|
161
162
|
)
|
162
163
|
chunksize = _max_chunks_flavors[self.flavor]
|
163
164
|
|
@@ -184,8 +185,8 @@ def read(
|
|
184
185
|
truncated_table_name = truncate_item_name(str(query_or_table), self.flavor)
|
185
186
|
if truncated_table_name != str(query_or_table) and not silent:
|
186
187
|
warn(
|
187
|
-
f"Table '{
|
188
|
-
+ f" will instead
|
188
|
+
f"Table '{query_or_table}' is too long for '{self.flavor}',"
|
189
|
+
+ f" will instead read the table '{truncated_table_name}'."
|
189
190
|
)
|
190
191
|
|
191
192
|
query_or_table = sql_item_name(str(query_or_table), self.flavor, schema)
|
@@ -204,6 +205,34 @@ def read(
|
|
204
205
|
|
205
206
|
chunk_list = []
|
206
207
|
chunk_hook_results = []
|
208
|
+
def _process_chunk(_chunk, _retry_on_failure: bool = True):
|
209
|
+
if not as_hook_results:
|
210
|
+
chunk_list.append(_chunk)
|
211
|
+
if chunk_hook is None:
|
212
|
+
return None
|
213
|
+
|
214
|
+
result = None
|
215
|
+
try:
|
216
|
+
result = chunk_hook(
|
217
|
+
_chunk,
|
218
|
+
workers=workers,
|
219
|
+
chunksize=chunksize,
|
220
|
+
debug=debug,
|
221
|
+
**kw
|
222
|
+
)
|
223
|
+
except Exception:
|
224
|
+
result = False, traceback.format_exc()
|
225
|
+
from meerschaum.utils.formatting import get_console
|
226
|
+
if not silent:
|
227
|
+
get_console().print_exception()
|
228
|
+
|
229
|
+
### If the chunk fails to process, try it again one more time.
|
230
|
+
if isinstance(result, tuple) and result[0] is False:
|
231
|
+
if _retry_on_failure:
|
232
|
+
return _process_chunk(_chunk, _retry_on_failure=False)
|
233
|
+
|
234
|
+
return result
|
235
|
+
|
207
236
|
try:
|
208
237
|
stream_results = not as_iterator and chunk_hook is not None and chunksize is not None
|
209
238
|
with warnings.catch_warnings():
|
@@ -235,52 +264,32 @@ def read(
|
|
235
264
|
)
|
236
265
|
else:
|
237
266
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
267
|
+
def get_chunk_generator(connectable):
|
268
|
+
chunk_generator = pd.read_sql_query(
|
269
|
+
formatted_query,
|
270
|
+
self.engine,
|
271
|
+
**read_sql_query_kwargs
|
272
|
+
)
|
273
|
+
to_return = (
|
274
|
+
chunk_generator
|
275
|
+
if as_iterator or chunksize is None
|
276
|
+
else (
|
277
|
+
list(pool.imap(_process_chunk, chunk_generator))
|
278
|
+
if as_hook_results
|
279
|
+
else None
|
244
280
|
)
|
281
|
+
)
|
282
|
+
return chunk_generator, to_return
|
283
|
+
|
284
|
+
if self.flavor in SKIP_READ_TRANSACTION_FLAVORS:
|
285
|
+
chunk_generator, to_return = get_chunk_generator(self.engine)
|
286
|
+
else:
|
287
|
+
with self.engine.begin() as transaction:
|
288
|
+
with transaction.execution_options(stream_results=stream_results) as connection:
|
289
|
+
chunk_generator, to_return = get_chunk_generator(connection)
|
245
290
|
|
246
|
-
|
247
|
-
|
248
|
-
return chunk_generator
|
249
|
-
|
250
|
-
### We must consume the generator in this context if using server-side cursors.
|
251
|
-
if stream_results:
|
252
|
-
|
253
|
-
pool = get_pool(workers=workers)
|
254
|
-
|
255
|
-
def _process_chunk(_chunk, _retry_on_failure: bool = True):
|
256
|
-
if not as_hook_results:
|
257
|
-
chunk_list.append(_chunk)
|
258
|
-
result = None
|
259
|
-
if chunk_hook is not None:
|
260
|
-
try:
|
261
|
-
result = chunk_hook(
|
262
|
-
_chunk,
|
263
|
-
workers = workers,
|
264
|
-
chunksize = chunksize,
|
265
|
-
debug = debug,
|
266
|
-
**kw
|
267
|
-
)
|
268
|
-
except Exception as e:
|
269
|
-
result = False, traceback.format_exc()
|
270
|
-
from meerschaum.utils.formatting import get_console
|
271
|
-
if not silent:
|
272
|
-
get_console().print_exception()
|
273
|
-
|
274
|
-
### If the chunk fails to process, try it again one more time.
|
275
|
-
if isinstance(result, tuple) and result[0] is False:
|
276
|
-
if _retry_on_failure:
|
277
|
-
return _process_chunk(_chunk, _retry_on_failure=False)
|
278
|
-
|
279
|
-
return result
|
280
|
-
|
281
|
-
chunk_hook_results = list(pool.imap(_process_chunk, chunk_generator))
|
282
|
-
if as_hook_results:
|
283
|
-
return chunk_hook_results
|
291
|
+
if to_return is not None:
|
292
|
+
return to_return
|
284
293
|
|
285
294
|
except Exception as e:
|
286
295
|
if debug:
|
meerschaum/core/Pipe/__init__.py
CHANGED
@@ -98,6 +98,8 @@ class Pipe:
|
|
98
98
|
attributes,
|
99
99
|
parameters,
|
100
100
|
columns,
|
101
|
+
indices,
|
102
|
+
indexes,
|
101
103
|
dtypes,
|
102
104
|
get_columns,
|
103
105
|
get_columns_types,
|
@@ -145,6 +147,7 @@ class Pipe:
|
|
145
147
|
location: Optional[str] = None,
|
146
148
|
parameters: Optional[Dict[str, Any]] = None,
|
147
149
|
columns: Union[Dict[str, str], List[str], None] = None,
|
150
|
+
indices: Optional[Dict[str, Union[str, List[str]]]] = None,
|
148
151
|
tags: Optional[List[str]] = None,
|
149
152
|
target: Optional[str] = None,
|
150
153
|
dtypes: Optional[Dict[str, str]] = None,
|
@@ -156,6 +159,7 @@ class Pipe:
|
|
156
159
|
connector_keys: Optional[str] = None,
|
157
160
|
metric_key: Optional[str] = None,
|
158
161
|
location_key: Optional[str] = None,
|
162
|
+
indexes: Union[Dict[str, str], List[str], None] = None,
|
159
163
|
):
|
160
164
|
"""
|
161
165
|
Parameters
|
@@ -174,10 +178,14 @@ class Pipe:
|
|
174
178
|
e.g. columns and other attributes.
|
175
179
|
You can edit these parameters with `edit pipes`.
|
176
180
|
|
177
|
-
columns:
|
181
|
+
columns: Union[Dict[str, str], List[str], None], default None
|
178
182
|
Set the `columns` dictionary of `parameters`.
|
179
183
|
If `parameters` is also provided, this dictionary is added under the `'columns'` key.
|
180
184
|
|
185
|
+
indices: Optional[Dict[str, Union[str, List[str]]]], default None
|
186
|
+
Set the `indices` dictionary of `parameters`.
|
187
|
+
If `parameters` is also provided, this dictionary is added under the `'indices'` key.
|
188
|
+
|
181
189
|
tags: Optional[List[str]], default None
|
182
190
|
A list of strings to be added under the `'tags'` key of `parameters`.
|
183
191
|
You can select pipes with certain tags using `--tags`.
|
@@ -255,6 +263,20 @@ class Pipe:
|
|
255
263
|
elif columns is not None:
|
256
264
|
warn(f"The provided columns are of invalid type '{type(columns)}'.")
|
257
265
|
|
266
|
+
indices = (
|
267
|
+
indices
|
268
|
+
or indexes
|
269
|
+
or self._attributes.get('parameters', {}).get('indices', None)
|
270
|
+
or self._attributes.get('parameters', {}).get('indexes', None)
|
271
|
+
) or columns
|
272
|
+
if isinstance(indices, dict):
|
273
|
+
indices_key = (
|
274
|
+
'indexes'
|
275
|
+
if 'indexes' in self._attributes['parameters']
|
276
|
+
else 'indices'
|
277
|
+
)
|
278
|
+
self._attributes['parameters'][indices_key] = indices
|
279
|
+
|
258
280
|
if isinstance(tags, (list, tuple)):
|
259
281
|
self._attributes['parameters']['tags'] = tags
|
260
282
|
elif tags is not None:
|
@@ -77,15 +77,69 @@ def columns(self) -> Union[Dict[str, str], None]:
|
|
77
77
|
|
78
78
|
|
79
79
|
@columns.setter
|
80
|
-
def columns(self,
|
80
|
+
def columns(self, _columns: Union[Dict[str, str], List[str]]) -> None:
|
81
81
|
"""
|
82
82
|
Override the columns dictionary of the in-memory pipe.
|
83
83
|
Call `meerschaum.Pipe.edit()` to persist changes.
|
84
84
|
"""
|
85
|
+
if isinstance(_columns, (list, tuple)):
|
86
|
+
_columns = {col: col for col in _columns}
|
85
87
|
if not isinstance(columns, dict):
|
86
|
-
warn(f"{self}.columns must be a dictionary, received {type(
|
88
|
+
warn(f"{self}.columns must be a dictionary, received {type(_columns)}.")
|
87
89
|
return
|
88
|
-
self.parameters['columns'] =
|
90
|
+
self.parameters['columns'] = _columns
|
91
|
+
|
92
|
+
|
93
|
+
@property
|
94
|
+
def indices(self) -> Union[Dict[str, Union[str, List[str]]], None]:
|
95
|
+
"""
|
96
|
+
Return the `indices` dictionary defined in `meerschaum.Pipe.parameters`.
|
97
|
+
"""
|
98
|
+
indices_key = (
|
99
|
+
'indexes'
|
100
|
+
if 'indexes' in self.parameters
|
101
|
+
else 'indices'
|
102
|
+
)
|
103
|
+
if indices_key not in self.parameters:
|
104
|
+
self.parameters[indices_key] = {}
|
105
|
+
_indices = self.parameters[indices_key]
|
106
|
+
if not isinstance(_indices, dict):
|
107
|
+
_indices = {}
|
108
|
+
self.parameters[indices_key] = _indices
|
109
|
+
return {**self.columns, **_indices}
|
110
|
+
|
111
|
+
|
112
|
+
@property
|
113
|
+
def indexes(self) -> Union[Dict[str, Union[str, List[str]]], None]:
|
114
|
+
"""
|
115
|
+
Alias for `meerschaum.Pipe.indices`.
|
116
|
+
"""
|
117
|
+
return self.indices
|
118
|
+
|
119
|
+
|
120
|
+
@indices.setter
|
121
|
+
def indices(self, _indices: Union[Dict[str, Union[str, List[str]]], List[str]]) -> None:
|
122
|
+
"""
|
123
|
+
Override the indices dictionary of the in-memory pipe.
|
124
|
+
Call `meerschaum.Pipe.edit()` to persist changes.
|
125
|
+
"""
|
126
|
+
if not isinstance(_indices, dict):
|
127
|
+
warn(f"{self}.indices must be a dictionary, received {type(_indices)}.")
|
128
|
+
return
|
129
|
+
indices_key = (
|
130
|
+
'indexes'
|
131
|
+
if 'indexes' in self.parameters
|
132
|
+
else 'indices'
|
133
|
+
)
|
134
|
+
self.parameters[indices_key] = _indices
|
135
|
+
|
136
|
+
|
137
|
+
@indexes.setter
|
138
|
+
def indexes(self, _indexes: Union[Dict[str, Union[str, List[str]]], List[str]]) -> None:
|
139
|
+
"""
|
140
|
+
Alias for `meerschaum.Pipe.indices`.
|
141
|
+
"""
|
142
|
+
self.indices = _indexes
|
89
143
|
|
90
144
|
|
91
145
|
@property
|
@@ -415,27 +469,55 @@ def guess_datetime(self) -> Union[str, None]:
|
|
415
469
|
"""
|
416
470
|
Try to determine a pipe's datetime column.
|
417
471
|
"""
|
418
|
-
|
472
|
+
_dtypes = self.dtypes
|
419
473
|
|
420
474
|
### Abort if the user explictly disallows a datetime index.
|
421
|
-
if 'datetime' in
|
422
|
-
if
|
475
|
+
if 'datetime' in _dtypes:
|
476
|
+
if _dtypes['datetime'] is None:
|
423
477
|
return None
|
424
478
|
|
479
|
+
from meerschaum.utils.dtypes import are_dtypes_equal
|
425
480
|
dt_cols = [
|
426
|
-
col
|
427
|
-
|
481
|
+
col
|
482
|
+
for col, typ in _dtypes.items()
|
483
|
+
if are_dtypes_equal(typ, 'datetime')
|
428
484
|
]
|
429
485
|
if not dt_cols:
|
430
486
|
return None
|
431
|
-
return dt_cols[0]
|
487
|
+
return dt_cols[0]
|
432
488
|
|
433
489
|
|
434
490
|
def get_indices(self) -> Dict[str, str]:
|
435
491
|
"""
|
436
|
-
Return a dictionary
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
492
|
+
Return a dictionary mapping index keys to their names on the database.
|
493
|
+
|
494
|
+
Returns
|
495
|
+
-------
|
496
|
+
A dictionary of index keys to column names.
|
497
|
+
"""
|
498
|
+
_parameters = self.parameters
|
499
|
+
_index_template = _parameters.get('index_template', "IX_{target}_{column_names}")
|
500
|
+
_indices = self.indices
|
501
|
+
_target = self.target
|
502
|
+
_column_names = {
|
503
|
+
ix: (
|
504
|
+
'_'.join(cols)
|
505
|
+
if isinstance(cols, (list, tuple))
|
506
|
+
else str(cols)
|
507
|
+
)
|
508
|
+
for ix, cols in _indices.items()
|
509
|
+
if cols
|
510
|
+
}
|
511
|
+
_index_names = {
|
512
|
+
ix: (
|
513
|
+
_index_template.format(
|
514
|
+
target=_target,
|
515
|
+
column_names=column_names,
|
516
|
+
connector_keys=self.connector_keys,
|
517
|
+
metric_key=self.connector_key,
|
518
|
+
location_key=self.location_key,
|
519
|
+
)
|
520
|
+
)
|
521
|
+
for ix, column_names in _column_names.items()
|
441
522
|
}
|
523
|
+
return _index_names
|
meerschaum/utils/dataframe.py
CHANGED
@@ -413,6 +413,7 @@ def parse_df_datetimes(
|
|
413
413
|
from meerschaum.utils.packages import import_pandas, attempt_import
|
414
414
|
from meerschaum.utils.debug import dprint
|
415
415
|
from meerschaum.utils.warnings import warn
|
416
|
+
from meerschaum.utils.misc import items_str
|
416
417
|
import traceback
|
417
418
|
pd = import_pandas()
|
418
419
|
pandas = attempt_import('pandas')
|
@@ -503,14 +504,14 @@ def parse_df_datetimes(
|
|
503
504
|
else:
|
504
505
|
df[datetime_cols] = df[datetime_cols].apply(
|
505
506
|
pd.to_datetime,
|
506
|
-
utc
|
507
|
-
axis
|
508
|
-
meta
|
507
|
+
utc=True,
|
508
|
+
axis=1,
|
509
|
+
meta={
|
509
510
|
col: 'datetime64[ns]'
|
510
511
|
for col in datetime_cols
|
511
512
|
}
|
512
513
|
)
|
513
|
-
except Exception
|
514
|
+
except Exception:
|
514
515
|
warn(
|
515
516
|
f"Unable to apply `pd.to_datetime` to {items_str(datetime_cols)}:\n"
|
516
517
|
+ f"{traceback.format_exc()}"
|
@@ -519,7 +520,7 @@ def parse_df_datetimes(
|
|
519
520
|
for dt in datetime_cols:
|
520
521
|
try:
|
521
522
|
df[dt] = df[dt].dt.tz_localize(None)
|
522
|
-
except Exception
|
523
|
+
except Exception:
|
523
524
|
warn(f"Unable to convert column '{dt}' to naive datetime:\n{traceback.format_exc()}")
|
524
525
|
|
525
526
|
return df
|
@@ -567,6 +568,9 @@ def get_json_cols(df: 'pd.DataFrame') -> List[str]:
|
|
567
568
|
-------
|
568
569
|
A list of columns to be encoded as JSON.
|
569
570
|
"""
|
571
|
+
if df is None:
|
572
|
+
return []
|
573
|
+
|
570
574
|
is_dask = 'dask' in df.__module__ if hasattr(df, '__module__') else False
|
571
575
|
if is_dask:
|
572
576
|
df = get_first_valid_dask_partition(df)
|
@@ -602,6 +606,8 @@ def get_numeric_cols(df: 'pd.DataFrame') -> List[str]:
|
|
602
606
|
-------
|
603
607
|
A list of columns to treat as numerics.
|
604
608
|
"""
|
609
|
+
if df is None:
|
610
|
+
return []
|
605
611
|
from decimal import Decimal
|
606
612
|
is_dask = 'dask' in df.__module__
|
607
613
|
if is_dask:
|
@@ -638,6 +644,8 @@ def get_uuid_cols(df: 'pd.DataFrame') -> List[str]:
|
|
638
644
|
-------
|
639
645
|
A list of columns to treat as numerics.
|
640
646
|
"""
|
647
|
+
if df is None:
|
648
|
+
return []
|
641
649
|
from uuid import UUID
|
642
650
|
is_dask = 'dask' in df.__module__
|
643
651
|
if is_dask:
|
@@ -883,6 +891,8 @@ def get_datetime_bound_from_df(
|
|
883
891
|
-------
|
884
892
|
The minimum or maximum datetime value in the dataframe, or `None`.
|
885
893
|
"""
|
894
|
+
if df is None:
|
895
|
+
return None
|
886
896
|
if not datetime_column:
|
887
897
|
return None
|
888
898
|
|
@@ -955,6 +965,8 @@ def get_unique_index_values(
|
|
955
965
|
-------
|
956
966
|
A dictionary mapping indices to unique values.
|
957
967
|
"""
|
968
|
+
if df is None:
|
969
|
+
return {}
|
958
970
|
if 'dataframe' in str(type(df)).lower():
|
959
971
|
pandas = mrsm.attempt_import('pandas')
|
960
972
|
return {
|
@@ -11,7 +11,12 @@ from __future__ import annotations
|
|
11
11
|
import importlib.util, os, pathlib, re
|
12
12
|
from meerschaum.utils.typing import Any, List, SuccessTuple, Optional, Union, Tuple, Dict, Iterable
|
13
13
|
from meerschaum.utils.threading import Lock, RLock
|
14
|
-
from meerschaum.utils.packages._packages import
|
14
|
+
from meerschaum.utils.packages._packages import (
|
15
|
+
packages,
|
16
|
+
all_packages,
|
17
|
+
get_install_names,
|
18
|
+
_MRSM_PACKAGE_ARCHIVES_PREFIX,
|
19
|
+
)
|
15
20
|
from meerschaum.utils.venv import (
|
16
21
|
activate_venv,
|
17
22
|
deactivate_venv,
|
@@ -35,14 +40,14 @@ _locks = {
|
|
35
40
|
}
|
36
41
|
_checked_for_updates = set()
|
37
42
|
_is_installed_first_check: Dict[str, bool] = {}
|
38
|
-
|
43
|
+
|
39
44
|
|
40
45
|
def get_module_path(
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
import_name: str,
|
47
|
+
venv: Optional[str] = 'mrsm',
|
48
|
+
debug: bool = False,
|
49
|
+
_try_install_name_on_fail: bool = True,
|
50
|
+
) -> Union[pathlib.Path, None]:
|
46
51
|
"""
|
47
52
|
Get a module's path without importing.
|
48
53
|
"""
|
@@ -232,10 +237,10 @@ def manually_import_module(
|
|
232
237
|
if check_update:
|
233
238
|
if need_update(
|
234
239
|
None,
|
235
|
-
import_name
|
236
|
-
version
|
237
|
-
check_pypi
|
238
|
-
debug
|
240
|
+
import_name=root_name,
|
241
|
+
version=_version,
|
242
|
+
check_pypi=check_pypi,
|
243
|
+
debug=debug,
|
239
244
|
):
|
240
245
|
if install:
|
241
246
|
if not pip_install(
|
@@ -491,6 +496,8 @@ def _get_package_metadata(import_name: str, venv: Optional[str]) -> Dict[str, st
|
|
491
496
|
import re
|
492
497
|
from meerschaum.config._paths import VIRTENV_RESOURCES_PATH
|
493
498
|
install_name = _import_to_install_name(import_name)
|
499
|
+
if install_name.startswith(_MRSM_PACKAGE_ARCHIVES_PREFIX):
|
500
|
+
return {}
|
494
501
|
_args = ['pip', 'show', install_name]
|
495
502
|
if venv is not None:
|
496
503
|
cache_dir_path = VIRTENV_RESOURCES_PATH / venv / 'cache'
|
@@ -586,7 +593,10 @@ def need_update(
|
|
586
593
|
_checked_for_updates.add(install_name)
|
587
594
|
|
588
595
|
_install_no_version = get_install_no_version(install_name)
|
589
|
-
required_version =
|
596
|
+
required_version = (
|
597
|
+
install_name
|
598
|
+
.replace(_install_no_version, '')
|
599
|
+
)
|
590
600
|
if ']' in required_version:
|
591
601
|
required_version = required_version.split(']')[1]
|
592
602
|
|
@@ -681,8 +691,8 @@ def need_update(
|
|
681
691
|
)
|
682
692
|
|
683
693
|
if 'a' in required_version:
|
684
|
-
required_version = required_version.replace('a', '-
|
685
|
-
version = version.replace('a', '-
|
694
|
+
required_version = required_version.replace('a', '-pre.').replace('+mrsm', '')
|
695
|
+
version = version.replace('a', '-pre.').replace('+mrsm', '')
|
686
696
|
try:
|
687
697
|
return (
|
688
698
|
(not semver.Version.parse(version).match(required_version))
|
@@ -780,7 +790,7 @@ def pip_install(
|
|
780
790
|
This includes version restrictions.
|
781
791
|
Use `_import_to_install_name()` to get the predefined `install_name` for a package
|
782
792
|
from its import name.
|
783
|
-
|
793
|
+
|
784
794
|
args: Optional[List[str]], default None
|
785
795
|
A list of command line arguments to pass to `pip`.
|
786
796
|
If not provided, default to `['--upgrade']` if `_uninstall` is `False`, else `[]`.
|
@@ -975,7 +985,11 @@ def pip_install(
|
|
975
985
|
pass
|
976
986
|
|
977
987
|
_packages = [
|
978
|
-
(
|
988
|
+
(
|
989
|
+
get_install_no_version(install_name)
|
990
|
+
if _uninstall or install_name.startswith(_MRSM_PACKAGE_ARCHIVES_PREFIX)
|
991
|
+
else install_name
|
992
|
+
)
|
979
993
|
for install_name in install_names
|
980
994
|
]
|
981
995
|
msg = "Installing packages:" if not _uninstall else "Uninstalling packages:"
|
@@ -1774,13 +1788,17 @@ def is_installed(
|
|
1774
1788
|
|
1775
1789
|
found = (
|
1776
1790
|
not need_update(
|
1777
|
-
None,
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1791
|
+
None,
|
1792
|
+
import_name=root_name,
|
1793
|
+
_run_determine_version=False,
|
1794
|
+
check_pypi=False,
|
1795
|
+
version=determine_version(
|
1796
|
+
spec_path,
|
1797
|
+
venv=venv,
|
1798
|
+
debug=debug,
|
1799
|
+
import_name=root_name,
|
1782
1800
|
),
|
1783
|
-
debug
|
1801
|
+
debug=debug,
|
1784
1802
|
)
|
1785
1803
|
) if spec_path is not None else False
|
1786
1804
|
|
@@ -16,9 +16,10 @@ packages dictionary is structured in the following schema:
|
|
16
16
|
from __future__ import annotations
|
17
17
|
from meerschaum.utils.typing import Dict
|
18
18
|
|
19
|
+
_MRSM_PACKAGE_ARCHIVES_PREFIX: str = "https://meerschaum.io/files/archives/wheels/"
|
20
|
+
|
19
21
|
packages: Dict[str, Dict[str, str]] = {
|
20
|
-
'required': {
|
21
|
-
},
|
22
|
+
'required': {},
|
22
23
|
'minimal': {},
|
23
24
|
'formatting': {
|
24
25
|
'pprintpp' : 'pprintpp>=0.4.0',
|
@@ -36,7 +37,7 @@ packages: Dict[str, Dict[str, str]] = {
|
|
36
37
|
'yaml' : 'PyYAML>=5.3.1',
|
37
38
|
'pip' : 'pip>=22.0.4',
|
38
39
|
'update_checker' : 'update-checker>=0.18.0',
|
39
|
-
'semver' : 'semver>=3.0.
|
40
|
+
'semver' : 'semver>=3.0.2',
|
40
41
|
'pathspec' : 'pathspec>=0.9.0',
|
41
42
|
'dateutil' : 'python-dateutil>=2.7.5',
|
42
43
|
'requests' : 'requests>=2.32.3',
|
@@ -51,10 +52,15 @@ packages: Dict[str, Dict[str, str]] = {
|
|
51
52
|
'more_itertools' : 'more-itertools>=8.7.0',
|
52
53
|
'fasteners' : 'fasteners>=0.19.0',
|
53
54
|
'virtualenv' : 'virtualenv>=20.1.0',
|
54
|
-
'attrs' : 'attrs
|
55
|
-
'apscheduler' : 'APScheduler>=4.0.0a5',
|
55
|
+
'attrs' : 'attrs>=24.2.0',
|
56
56
|
'uv' : 'uv>=0.2.11',
|
57
57
|
},
|
58
|
+
'_internal' : {
|
59
|
+
'apscheduler' : (
|
60
|
+
f"{_MRSM_PACKAGE_ARCHIVES_PREFIX}"
|
61
|
+
"APScheduler-4.0.0a5.post75+mrsm-py3-none-any.whl>=4.0.0a5"
|
62
|
+
),
|
63
|
+
},
|
58
64
|
'jobs': {
|
59
65
|
'dill' : 'dill>=0.3.3',
|
60
66
|
'daemon' : 'python-daemon>=0.2.3',
|
@@ -179,15 +185,25 @@ def get_install_names():
|
|
179
185
|
install_names[get_install_no_version(_install_name)] = _import_name
|
180
186
|
return install_names
|
181
187
|
|
182
|
-
|
188
|
+
|
189
|
+
skip_groups = {
|
190
|
+
'docs',
|
191
|
+
'build',
|
192
|
+
'cli',
|
193
|
+
'dev-tools',
|
194
|
+
'portable',
|
195
|
+
'extras',
|
196
|
+
'stack',
|
197
|
+
'drivers-extras',
|
198
|
+
'_internal',
|
199
|
+
}
|
183
200
|
full = []
|
184
201
|
_full = {}
|
185
202
|
for group, import_names in packages.items():
|
186
203
|
### omit 'cli' and 'docs' from 'full'
|
187
|
-
if group in skip_groups:
|
204
|
+
if group in skip_groups or group.startswith('_'):
|
188
205
|
continue
|
189
206
|
full += [ install_name for import_name, install_name in import_names.items() ]
|
190
207
|
for import_name, install_name in import_names.items():
|
191
208
|
_full[import_name] = install_name
|
192
209
|
packages['full'] = _full
|
193
|
-
|
meerschaum/utils/schedule.py
CHANGED
@@ -140,7 +140,7 @@ def parse_schedule(schedule: str, now: Optional[datetime] = None):
|
|
140
140
|
"""
|
141
141
|
Parse a schedule string (e.g. 'daily') into a Trigger object.
|
142
142
|
"""
|
143
|
-
from meerschaum.utils.misc import items_str, is_int
|
143
|
+
from meerschaum.utils.misc import items_str, is_int, filter_keywords
|
144
144
|
(
|
145
145
|
apscheduler_triggers_cron,
|
146
146
|
apscheduler_triggers_interval,
|
@@ -204,10 +204,14 @@ def parse_schedule(schedule: str, now: Optional[datetime] = None):
|
|
204
204
|
|
205
205
|
trigger = (
|
206
206
|
apscheduler_triggers_interval.IntervalTrigger(
|
207
|
-
**
|
208
|
-
|
209
|
-
|
210
|
-
|
207
|
+
**filter_keywords(
|
208
|
+
apscheduler_triggers_interval.IntervalTrigger.__init__,
|
209
|
+
**{
|
210
|
+
schedule_unit: schedule_num,
|
211
|
+
'start_time': starting_ts,
|
212
|
+
'start_date': starting_ts,
|
213
|
+
}
|
214
|
+
)
|
211
215
|
)
|
212
216
|
if schedule_unit not in ('months', 'years') else (
|
213
217
|
apscheduler_triggers_calendarinterval.CalendarIntervalTrigger(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: meerschaum
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.5.0
|
4
4
|
Summary: Sync Time-Series Pipes with Meerschaum
|
5
5
|
Home-page: https://meerschaum.io
|
6
6
|
Author: Bennett Meares
|
@@ -64,7 +64,7 @@ Requires-Dist: setuptools >=63.3.0 ; extra == 'api'
|
|
64
64
|
Requires-Dist: PyYAML >=5.3.1 ; extra == 'api'
|
65
65
|
Requires-Dist: pip >=22.0.4 ; extra == 'api'
|
66
66
|
Requires-Dist: update-checker >=0.18.0 ; extra == 'api'
|
67
|
-
Requires-Dist: semver >=3.0.
|
67
|
+
Requires-Dist: semver >=3.0.2 ; extra == 'api'
|
68
68
|
Requires-Dist: pathspec >=0.9.0 ; extra == 'api'
|
69
69
|
Requires-Dist: python-dateutil >=2.7.5 ; extra == 'api'
|
70
70
|
Requires-Dist: requests >=2.32.3 ; extra == 'api'
|
@@ -79,8 +79,7 @@ Requires-Dist: prompt-toolkit >=3.0.39 ; extra == 'api'
|
|
79
79
|
Requires-Dist: more-itertools >=8.7.0 ; extra == 'api'
|
80
80
|
Requires-Dist: fasteners >=0.19.0 ; extra == 'api'
|
81
81
|
Requires-Dist: virtualenv >=20.1.0 ; extra == 'api'
|
82
|
-
Requires-Dist: attrs
|
83
|
-
Requires-Dist: APScheduler >=4.0.0a5 ; extra == 'api'
|
82
|
+
Requires-Dist: attrs >=24.2.0 ; extra == 'api'
|
84
83
|
Requires-Dist: uv >=0.2.11 ; extra == 'api'
|
85
84
|
Requires-Dist: pprintpp >=0.4.0 ; extra == 'api'
|
86
85
|
Requires-Dist: asciitree >=0.3.3 ; extra == 'api'
|
@@ -117,7 +116,7 @@ Requires-Dist: setuptools >=63.3.0 ; extra == 'core'
|
|
117
116
|
Requires-Dist: PyYAML >=5.3.1 ; extra == 'core'
|
118
117
|
Requires-Dist: pip >=22.0.4 ; extra == 'core'
|
119
118
|
Requires-Dist: update-checker >=0.18.0 ; extra == 'core'
|
120
|
-
Requires-Dist: semver >=3.0.
|
119
|
+
Requires-Dist: semver >=3.0.2 ; extra == 'core'
|
121
120
|
Requires-Dist: pathspec >=0.9.0 ; extra == 'core'
|
122
121
|
Requires-Dist: python-dateutil >=2.7.5 ; extra == 'core'
|
123
122
|
Requires-Dist: requests >=2.32.3 ; extra == 'core'
|
@@ -132,8 +131,7 @@ Requires-Dist: prompt-toolkit >=3.0.39 ; extra == 'core'
|
|
132
131
|
Requires-Dist: more-itertools >=8.7.0 ; extra == 'core'
|
133
132
|
Requires-Dist: fasteners >=0.19.0 ; extra == 'core'
|
134
133
|
Requires-Dist: virtualenv >=20.1.0 ; extra == 'core'
|
135
|
-
Requires-Dist: attrs
|
136
|
-
Requires-Dist: APScheduler >=4.0.0a5 ; extra == 'core'
|
134
|
+
Requires-Dist: attrs >=24.2.0 ; extra == 'core'
|
137
135
|
Requires-Dist: uv >=0.2.11 ; extra == 'core'
|
138
136
|
Provides-Extra: dash
|
139
137
|
Requires-Dist: Flask-Compress >=1.10.1 ; extra == 'dash'
|
@@ -203,7 +201,7 @@ Requires-Dist: setuptools >=63.3.0 ; extra == 'full'
|
|
203
201
|
Requires-Dist: PyYAML >=5.3.1 ; extra == 'full'
|
204
202
|
Requires-Dist: pip >=22.0.4 ; extra == 'full'
|
205
203
|
Requires-Dist: update-checker >=0.18.0 ; extra == 'full'
|
206
|
-
Requires-Dist: semver >=3.0.
|
204
|
+
Requires-Dist: semver >=3.0.2 ; extra == 'full'
|
207
205
|
Requires-Dist: pathspec >=0.9.0 ; extra == 'full'
|
208
206
|
Requires-Dist: python-dateutil >=2.7.5 ; extra == 'full'
|
209
207
|
Requires-Dist: requests >=2.32.3 ; extra == 'full'
|
@@ -218,8 +216,7 @@ Requires-Dist: prompt-toolkit >=3.0.39 ; extra == 'full'
|
|
218
216
|
Requires-Dist: more-itertools >=8.7.0 ; extra == 'full'
|
219
217
|
Requires-Dist: fasteners >=0.19.0 ; extra == 'full'
|
220
218
|
Requires-Dist: virtualenv >=20.1.0 ; extra == 'full'
|
221
|
-
Requires-Dist: attrs
|
222
|
-
Requires-Dist: APScheduler >=4.0.0a5 ; extra == 'full'
|
219
|
+
Requires-Dist: attrs >=24.2.0 ; extra == 'full'
|
223
220
|
Requires-Dist: uv >=0.2.11 ; extra == 'full'
|
224
221
|
Requires-Dist: dill >=0.3.3 ; extra == 'full'
|
225
222
|
Requires-Dist: python-daemon >=0.2.3 ; extra == 'full'
|
@@ -299,7 +296,7 @@ Requires-Dist: setuptools >=63.3.0 ; extra == 'sql'
|
|
299
296
|
Requires-Dist: PyYAML >=5.3.1 ; extra == 'sql'
|
300
297
|
Requires-Dist: pip >=22.0.4 ; extra == 'sql'
|
301
298
|
Requires-Dist: update-checker >=0.18.0 ; extra == 'sql'
|
302
|
-
Requires-Dist: semver >=3.0.
|
299
|
+
Requires-Dist: semver >=3.0.2 ; extra == 'sql'
|
303
300
|
Requires-Dist: pathspec >=0.9.0 ; extra == 'sql'
|
304
301
|
Requires-Dist: python-dateutil >=2.7.5 ; extra == 'sql'
|
305
302
|
Requires-Dist: requests >=2.32.3 ; extra == 'sql'
|
@@ -314,8 +311,7 @@ Requires-Dist: prompt-toolkit >=3.0.39 ; extra == 'sql'
|
|
314
311
|
Requires-Dist: more-itertools >=8.7.0 ; extra == 'sql'
|
315
312
|
Requires-Dist: fasteners >=0.19.0 ; extra == 'sql'
|
316
313
|
Requires-Dist: virtualenv >=20.1.0 ; extra == 'sql'
|
317
|
-
Requires-Dist: attrs
|
318
|
-
Requires-Dist: APScheduler >=4.0.0a5 ; extra == 'sql'
|
314
|
+
Requires-Dist: attrs >=24.2.0 ; extra == 'sql'
|
319
315
|
Requires-Dist: uv >=0.2.11 ; extra == 'sql'
|
320
316
|
Provides-Extra: stack
|
321
317
|
Requires-Dist: docker-compose >=1.29.2 ; extra == 'stack'
|
@@ -49,7 +49,7 @@ meerschaum/actions/stop.py,sha256=5fdUw70YN-yuUWrC-NhA88cxr9FZ5NbssbQ8xXO8nFU,46
|
|
49
49
|
meerschaum/actions/sync.py,sha256=uXneLSykNH0LapE4kn_9fzwUQ-kJcRUzJ42pyuoFNaI,17161
|
50
50
|
meerschaum/actions/tag.py,sha256=SJf5qFW0ccLXjqlTdkK_0MCcrCMdg6xhYrhKdco0hdA,3053
|
51
51
|
meerschaum/actions/uninstall.py,sha256=tBXhdXggSieGEQe4EPGxpgMK0MZTJCweNvAJ9-59El0,5776
|
52
|
-
meerschaum/actions/upgrade.py,sha256=
|
52
|
+
meerschaum/actions/upgrade.py,sha256=AjuC93Te-I_GWwIfuNkFJ2q1zVHDQ2Oco34S4JgK2iA,6485
|
53
53
|
meerschaum/actions/verify.py,sha256=tY5slGpHiWiE0v9TDnjbmxSKn86zBnu9WBpixUgKNQU,4885
|
54
54
|
meerschaum/api/__init__.py,sha256=5q2XelZvqZSyfCyGIf1mlrWVxrsDaG2_I4L5ACeqMso,8456
|
55
55
|
meerschaum/api/_chain.py,sha256=h8-WXUGXX6AqzdALfsBC5uv0FkAcLdHJXCGzqzuq89k,875
|
@@ -143,7 +143,7 @@ meerschaum/config/_preprocess.py,sha256=-AEA8m_--KivZwTQ1sWN6LTn5sio_fUr2XZ51BO6
|
|
143
143
|
meerschaum/config/_read_config.py,sha256=oxnLjuhy6JBBld886FkBX07wUdkpzEzTItYMUa9qw1Q,14688
|
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=wtE11BYLrlYRUUbwWnx12ho0mgFDv-guHaABMWLfMLY,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=gGVxXgNnGb9u25iF__IiNPlZt1BLUVmHmFJ0jvnJg3Q,10548
|
@@ -173,12 +173,12 @@ meerschaum/connectors/plugin/__init__.py,sha256=pwF7TGY4WNz2_HaVdmK4rPQ9ZwTOEuPH
|
|
173
173
|
meerschaum/connectors/sql/_SQLConnector.py,sha256=QlC2Af7AM7bIlPHjUO57mTyzot3zU7o83jegADMxnBE,11829
|
174
174
|
meerschaum/connectors/sql/__init__.py,sha256=3cqYiDkVasn7zWdtOTAZbT4bo95AuvGOmDD2TkaAxtw,205
|
175
175
|
meerschaum/connectors/sql/_cli.py,sha256=1SgnWeMIAihoxp4FzbNrcq1npXf0dSOQnCntpU9hUXA,4405
|
176
|
-
meerschaum/connectors/sql/_create_engine.py,sha256=
|
177
|
-
meerschaum/connectors/sql/_fetch.py,sha256=
|
178
|
-
meerschaum/connectors/sql/_instance.py,sha256=
|
179
|
-
meerschaum/connectors/sql/_pipes.py,sha256
|
176
|
+
meerschaum/connectors/sql/_create_engine.py,sha256=zqeu1xHOw3n3Zgfjx-diy2aoynfdOlfOjwFuRrzB028,10452
|
177
|
+
meerschaum/connectors/sql/_fetch.py,sha256=J5e9EZrb70neXq8p78LFTTJiVukMIEKHuTXlILHDDGI,13005
|
178
|
+
meerschaum/connectors/sql/_instance.py,sha256=3KJI3ImwWAJkUfdZIrSL24pcW6Nic8wo5IUeGth9HP4,6459
|
179
|
+
meerschaum/connectors/sql/_pipes.py,sha256=8qoiv4nmvU4TVMTtvzWbPcqhq-izZ-C2338t4NFGQ0I,101302
|
180
180
|
meerschaum/connectors/sql/_plugins.py,sha256=wbxcNxqTtjfDsxPvdVGTllasYf6NHHzODaQ72hEUSBQ,8135
|
181
|
-
meerschaum/connectors/sql/_sql.py,sha256=
|
181
|
+
meerschaum/connectors/sql/_sql.py,sha256=gw8dy6-s8VqxANO9-tXIXFqCwPT_GrktG81AAQgqmPE,36032
|
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
|
@@ -191,8 +191,8 @@ meerschaum/connectors/valkey/_pipes.py,sha256=7GNDGoVDIULyGUjUisckErvRlrcnN4WkML
|
|
191
191
|
meerschaum/connectors/valkey/_plugins.py,sha256=ZqiEW4XZCOpw4G8DUK2IKY6Qrph4mYfTjgXWimgakYY,6267
|
192
192
|
meerschaum/connectors/valkey/_users.py,sha256=AS1vLarrkDA9yPK644GWwRiQiTZVa9x3nlLpyntq40g,7730
|
193
193
|
meerschaum/core/__init__.py,sha256=tjASW10n9uLV6bYhcwP4rggh-ESXSJzgxpSBbVsuISs,251
|
194
|
-
meerschaum/core/Pipe/__init__.py,sha256=
|
195
|
-
meerschaum/core/Pipe/_attributes.py,sha256=
|
194
|
+
meerschaum/core/Pipe/__init__.py,sha256=2dOEf8e3uwkwIac2sMbu3RZDyAAFzD7h6z9X-Lyb1Ds,17649
|
195
|
+
meerschaum/core/Pipe/_attributes.py,sha256=tB6v-KT7CbBaNTvgLbYFMpE4M73nicql1KWO9QT2ctg,15490
|
196
196
|
meerschaum/core/Pipe/_bootstrap.py,sha256=evyi07kkzAVMj66HfZkbYdcWk_oHUDsl6f13EnSPMYs,7723
|
197
197
|
meerschaum/core/Pipe/_clear.py,sha256=yFAYQnDmL3m6DzyAutgnBDXSOL9gjIrLvlQXd86YFV0,2193
|
198
198
|
meerschaum/core/Pipe/_copy.py,sha256=PcOeNUb0B4-HehTAAnBpjyT4uLLTR6VQOarY0SFA9wk,2912
|
@@ -219,7 +219,7 @@ meerschaum/plugins/__init__.py,sha256=6krcqaMKyzuVqesXMqEL0XEy2SJQ4xfNt2-oI_fJ6v
|
|
219
219
|
meerschaum/plugins/bootstrap.py,sha256=VwjpZAuYdqPJW0YoVgAoM_taHkdQHqP902-8T7OWWCI,11339
|
220
220
|
meerschaum/utils/__init__.py,sha256=QrK1K9hIbPCRCM5k2nZGFqGnrqhA0Eh-iSmCU7FG6Cs,612
|
221
221
|
meerschaum/utils/_get_pipes.py,sha256=tu4xKPoDn79Dz2kWM13cXTP4DSCkn-3G9M8KiLftopw,11073
|
222
|
-
meerschaum/utils/dataframe.py,sha256=
|
222
|
+
meerschaum/utils/dataframe.py,sha256=Sg4tUZbqgstwQnnnNR-zALzxJ6kRMeej_4n29HC9pWU,42157
|
223
223
|
meerschaum/utils/debug.py,sha256=GyIzJmunkoPnOcZNYVQdT4Sgd-aOb5MI2VbIgATOjIQ,3695
|
224
224
|
meerschaum/utils/interactive.py,sha256=t-6jWozXSqL7lYGDHuwiOjTgr-UKhdcg61q_eR5mikI,3196
|
225
225
|
meerschaum/utils/misc.py,sha256=OijhS1TMjlqkDvahbxhqfUdo0Myeor-kTKrvqqG8wN0,46349
|
@@ -227,7 +227,7 @@ meerschaum/utils/networking.py,sha256=Sr_eYUGW8_UV9-k9LqRFf7xLtbUcsDucODyLCRsFRU
|
|
227
227
|
meerschaum/utils/pool.py,sha256=vkE42af4fjrTEJTxf6Ek3xGucm1MtEkpsSEiaVzNKHs,2655
|
228
228
|
meerschaum/utils/process.py,sha256=9O8PPPJjY9Q5W2f39I3B3lFU6TlSiRiI3bgrzdOOyOw,7843
|
229
229
|
meerschaum/utils/prompt.py,sha256=6J--mZJ_NcEdSX6KMjtY4fXXezyILLHP24VdxFFqOIc,18985
|
230
|
-
meerschaum/utils/schedule.py,sha256=
|
230
|
+
meerschaum/utils/schedule.py,sha256=zKOtfVdr1QRSZYBOSrO2MRIz8DTMbkWfQA6CjahbSso,11115
|
231
231
|
meerschaum/utils/sql.py,sha256=R_hX92brvZDqID7c85-PNUVVR6RWXGXEgn1vFpHmi88,49869
|
232
232
|
meerschaum/utils/threading.py,sha256=3N8JXPAnwqJiSjuQcbbJg3Rv9-CCUMJpeQRfKFR7MaA,2489
|
233
233
|
meerschaum/utils/typing.py,sha256=U3MC347sh1umpa3Xr1k71eADyDmk4LB6TnVCpq8dVzI,2830
|
@@ -246,16 +246,16 @@ meerschaum/utils/formatting/_jobs.py,sha256=izsqPJhTtUkXUUtWnbXtReYsUYwulXtci3pB
|
|
246
246
|
meerschaum/utils/formatting/_pipes.py,sha256=840O5rg2aHhQoraCDOh2ZtBo43_W2W6R60yYufEoXp8,19494
|
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=
|
250
|
-
meerschaum/utils/packages/_packages.py,sha256=
|
249
|
+
meerschaum/utils/packages/__init__.py,sha256=KNs1Qc8-DX7r6LlZxyl9-Qr2FnsCtZfjSbiwo-sGNf8,64196
|
250
|
+
meerschaum/utils/packages/_packages.py,sha256=L8G9mQtiDyFp2pKesHufZrtbPAty0DH4u8k2wmCTxVY,8687
|
251
251
|
meerschaum/utils/packages/lazy_loader.py,sha256=VHnph3VozH29R4JnSSBfwtA5WKZYZQFT_GeQSShCnuc,2540
|
252
252
|
meerschaum/utils/venv/_Venv.py,sha256=sBnlmxHdAh2bx8btfVoD79-H9-cYsv5lP02IIXkyECs,3553
|
253
253
|
meerschaum/utils/venv/__init__.py,sha256=f3oi67lXYPLKJrnRW9lae7M3A8SFiC7DzaMoBdCVUFs,24609
|
254
|
-
meerschaum-2.
|
255
|
-
meerschaum-2.
|
256
|
-
meerschaum-2.
|
257
|
-
meerschaum-2.
|
258
|
-
meerschaum-2.
|
259
|
-
meerschaum-2.
|
260
|
-
meerschaum-2.
|
261
|
-
meerschaum-2.
|
254
|
+
meerschaum-2.5.0.dist-info/LICENSE,sha256=jG2zQEdRNt88EgHUWPpXVWmOrOduUQRx7MnYV9YIPaw,11359
|
255
|
+
meerschaum-2.5.0.dist-info/METADATA,sha256=oUofV2VmX4Ip1K7Sg8Hj-H0JYCwJjfMcLWSJPkLm0-s,24605
|
256
|
+
meerschaum-2.5.0.dist-info/NOTICE,sha256=OTA9Fcthjf5BRvWDDIcBC_xfLpeDV-RPZh3M-HQBRtQ,114
|
257
|
+
meerschaum-2.5.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
258
|
+
meerschaum-2.5.0.dist-info/entry_points.txt,sha256=5YBVzibw-0rNA_1VjB16z5GABsOGf-CDhW4yqH8C7Gc,88
|
259
|
+
meerschaum-2.5.0.dist-info/top_level.txt,sha256=bNoSiDj0El6buocix-FRoAtJOeq1qOF5rRm2u9i7Q6A,11
|
260
|
+
meerschaum-2.5.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
261
|
+
meerschaum-2.5.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|