meerschaum 2.9.4__py3-none-any.whl → 3.0.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/__init__.py +5 -2
- meerschaum/_internal/__init__.py +1 -0
- meerschaum/_internal/arguments/_parse_arguments.py +4 -4
- meerschaum/_internal/arguments/_parser.py +33 -4
- meerschaum/_internal/cli/__init__.py +6 -0
- meerschaum/_internal/cli/daemons.py +103 -0
- meerschaum/_internal/cli/entry.py +220 -0
- meerschaum/_internal/cli/workers.py +435 -0
- meerschaum/_internal/docs/index.py +48 -2
- meerschaum/_internal/entry.py +50 -14
- meerschaum/_internal/shell/Shell.py +121 -29
- meerschaum/_internal/shell/__init__.py +4 -1
- meerschaum/_internal/static.py +359 -0
- meerschaum/_internal/term/TermPageHandler.py +1 -2
- meerschaum/_internal/term/__init__.py +40 -6
- meerschaum/_internal/term/tools.py +33 -8
- meerschaum/actions/__init__.py +6 -4
- meerschaum/actions/api.py +53 -13
- meerschaum/actions/attach.py +1 -0
- meerschaum/actions/bootstrap.py +8 -8
- meerschaum/actions/delete.py +4 -2
- meerschaum/actions/edit.py +171 -25
- meerschaum/actions/login.py +8 -8
- meerschaum/actions/register.py +143 -6
- meerschaum/actions/reload.py +22 -5
- meerschaum/actions/restart.py +14 -0
- meerschaum/actions/show.py +184 -31
- meerschaum/actions/start.py +166 -17
- meerschaum/actions/stop.py +38 -2
- meerschaum/actions/sync.py +7 -2
- meerschaum/actions/tag.py +9 -8
- meerschaum/actions/verify.py +5 -8
- meerschaum/api/__init__.py +45 -15
- meerschaum/api/_events.py +46 -4
- meerschaum/api/_oauth2.py +162 -9
- meerschaum/api/_tokens.py +102 -0
- meerschaum/api/dash/__init__.py +0 -3
- meerschaum/api/dash/callbacks/__init__.py +1 -0
- meerschaum/api/dash/callbacks/custom.py +4 -3
- meerschaum/api/dash/callbacks/dashboard.py +228 -117
- meerschaum/api/dash/callbacks/jobs.py +14 -7
- meerschaum/api/dash/callbacks/login.py +10 -1
- meerschaum/api/dash/callbacks/pipes.py +194 -14
- meerschaum/api/dash/callbacks/plugins.py +0 -1
- meerschaum/api/dash/callbacks/register.py +10 -3
- meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
- meerschaum/api/dash/callbacks/tokens.py +389 -0
- meerschaum/api/dash/components.py +36 -15
- meerschaum/api/dash/jobs.py +1 -1
- meerschaum/api/dash/keys.py +35 -93
- meerschaum/api/dash/pages/__init__.py +2 -1
- meerschaum/api/dash/pages/dashboard.py +1 -20
- meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
- meerschaum/api/dash/pages/login.py +2 -2
- meerschaum/api/dash/pages/pipes.py +16 -5
- meerschaum/api/dash/pages/settings/password_reset.py +1 -1
- meerschaum/api/dash/pages/tokens.py +53 -0
- meerschaum/api/dash/pipes.py +438 -88
- meerschaum/api/dash/sessions.py +12 -0
- meerschaum/api/dash/tokens.py +603 -0
- meerschaum/api/dash/websockets.py +1 -1
- meerschaum/api/dash/webterm.py +18 -6
- meerschaum/api/models/__init__.py +23 -3
- meerschaum/api/models/_actions.py +22 -0
- meerschaum/api/models/_pipes.py +91 -7
- meerschaum/api/models/_tokens.py +81 -0
- meerschaum/api/resources/static/css/dash.css +16 -0
- meerschaum/api/resources/static/js/terminado.js +3 -0
- meerschaum/api/resources/static/js/xterm-addon-unicode11.js +2 -0
- meerschaum/api/resources/templates/termpage.html +13 -0
- meerschaum/api/routes/__init__.py +1 -0
- meerschaum/api/routes/_actions.py +3 -4
- meerschaum/api/routes/_connectors.py +3 -7
- meerschaum/api/routes/_jobs.py +26 -35
- meerschaum/api/routes/_login.py +120 -15
- meerschaum/api/routes/_misc.py +5 -10
- meerschaum/api/routes/_pipes.py +178 -143
- meerschaum/api/routes/_plugins.py +38 -28
- meerschaum/api/routes/_tokens.py +236 -0
- meerschaum/api/routes/_users.py +47 -35
- meerschaum/api/routes/_version.py +3 -3
- meerschaum/api/routes/_webterm.py +3 -3
- meerschaum/config/__init__.py +100 -30
- meerschaum/config/_default.py +132 -64
- meerschaum/config/_edit.py +38 -32
- meerschaum/config/_formatting.py +2 -0
- meerschaum/config/_patch.py +10 -8
- meerschaum/config/_paths.py +133 -13
- meerschaum/config/_read_config.py +87 -36
- meerschaum/config/_sync.py +6 -3
- meerschaum/config/_version.py +1 -1
- meerschaum/config/environment.py +262 -0
- meerschaum/config/stack/__init__.py +37 -15
- meerschaum/config/static.py +18 -0
- meerschaum/connectors/_Connector.py +11 -6
- meerschaum/connectors/__init__.py +41 -22
- meerschaum/connectors/api/_APIConnector.py +34 -6
- meerschaum/connectors/api/_actions.py +2 -2
- meerschaum/connectors/api/_jobs.py +12 -1
- meerschaum/connectors/api/_login.py +33 -7
- meerschaum/connectors/api/_misc.py +2 -2
- meerschaum/connectors/api/_pipes.py +23 -32
- meerschaum/connectors/api/_plugins.py +2 -2
- meerschaum/connectors/api/_request.py +1 -1
- meerschaum/connectors/api/_tokens.py +146 -0
- meerschaum/connectors/api/_users.py +70 -58
- meerschaum/connectors/instance/_InstanceConnector.py +83 -0
- meerschaum/connectors/instance/__init__.py +10 -0
- meerschaum/connectors/instance/_pipes.py +442 -0
- meerschaum/connectors/instance/_plugins.py +159 -0
- meerschaum/connectors/instance/_tokens.py +317 -0
- meerschaum/connectors/instance/_users.py +188 -0
- meerschaum/connectors/parse.py +5 -2
- meerschaum/connectors/sql/_SQLConnector.py +22 -5
- meerschaum/connectors/sql/_cli.py +12 -11
- meerschaum/connectors/sql/_create_engine.py +12 -168
- meerschaum/connectors/sql/_fetch.py +2 -18
- meerschaum/connectors/sql/_pipes.py +295 -278
- meerschaum/connectors/sql/_plugins.py +29 -0
- meerschaum/connectors/sql/_sql.py +47 -22
- meerschaum/connectors/sql/_users.py +36 -2
- meerschaum/connectors/sql/tables/__init__.py +254 -122
- meerschaum/connectors/valkey/_ValkeyConnector.py +5 -7
- meerschaum/connectors/valkey/_pipes.py +60 -31
- meerschaum/connectors/valkey/_plugins.py +2 -26
- meerschaum/core/Pipe/__init__.py +115 -85
- meerschaum/core/Pipe/_attributes.py +425 -124
- meerschaum/core/Pipe/_bootstrap.py +54 -24
- meerschaum/core/Pipe/_cache.py +555 -0
- meerschaum/core/Pipe/_clear.py +0 -11
- meerschaum/core/Pipe/_data.py +96 -68
- meerschaum/core/Pipe/_deduplicate.py +0 -13
- meerschaum/core/Pipe/_delete.py +12 -21
- meerschaum/core/Pipe/_drop.py +11 -23
- meerschaum/core/Pipe/_dtypes.py +49 -19
- meerschaum/core/Pipe/_edit.py +14 -4
- meerschaum/core/Pipe/_fetch.py +1 -1
- meerschaum/core/Pipe/_index.py +8 -14
- meerschaum/core/Pipe/_show.py +5 -5
- meerschaum/core/Pipe/_sync.py +123 -204
- meerschaum/core/Pipe/_verify.py +4 -4
- meerschaum/{plugins → core/Plugin}/_Plugin.py +16 -12
- meerschaum/core/Plugin/__init__.py +1 -1
- meerschaum/core/Token/_Token.py +220 -0
- meerschaum/core/Token/__init__.py +12 -0
- meerschaum/core/User/_User.py +35 -10
- meerschaum/core/User/__init__.py +9 -1
- meerschaum/core/__init__.py +1 -0
- meerschaum/jobs/_Executor.py +88 -4
- meerschaum/jobs/_Job.py +149 -38
- meerschaum/jobs/__init__.py +3 -2
- meerschaum/jobs/systemd.py +8 -3
- meerschaum/models/__init__.py +35 -0
- meerschaum/models/pipes.py +247 -0
- meerschaum/models/tokens.py +38 -0
- meerschaum/models/users.py +26 -0
- meerschaum/plugins/__init__.py +301 -88
- meerschaum/plugins/bootstrap.py +510 -4
- meerschaum/utils/_get_pipes.py +97 -30
- meerschaum/utils/daemon/Daemon.py +199 -43
- meerschaum/utils/daemon/FileDescriptorInterceptor.py +0 -1
- meerschaum/utils/daemon/RotatingFile.py +63 -36
- meerschaum/utils/daemon/StdinFile.py +53 -13
- meerschaum/utils/daemon/__init__.py +47 -6
- meerschaum/utils/daemon/_names.py +6 -3
- meerschaum/utils/dataframe.py +480 -82
- meerschaum/utils/debug.py +49 -19
- meerschaum/utils/dtypes/__init__.py +478 -37
- meerschaum/utils/dtypes/sql.py +369 -29
- meerschaum/utils/formatting/__init__.py +5 -2
- meerschaum/utils/formatting/_jobs.py +1 -1
- meerschaum/utils/formatting/_pipes.py +52 -50
- meerschaum/utils/formatting/_pprint.py +1 -0
- meerschaum/utils/formatting/_shell.py +44 -18
- meerschaum/utils/misc.py +268 -186
- meerschaum/utils/packages/__init__.py +25 -40
- meerschaum/utils/packages/_packages.py +42 -34
- meerschaum/utils/pipes.py +213 -0
- meerschaum/utils/process.py +2 -2
- meerschaum/utils/prompt.py +175 -144
- meerschaum/utils/schedule.py +2 -1
- meerschaum/utils/sql.py +135 -49
- meerschaum/utils/threading.py +42 -0
- meerschaum/utils/typing.py +1 -4
- meerschaum/utils/venv/_Venv.py +2 -2
- meerschaum/utils/venv/__init__.py +7 -7
- meerschaum/utils/warnings.py +19 -13
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/METADATA +94 -96
- meerschaum-3.0.0.dist-info/RECORD +289 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/WHEEL +1 -1
- meerschaum-3.0.0.dist-info/licenses/NOTICE +2 -0
- meerschaum/api/models/_interfaces.py +0 -15
- meerschaum/api/models/_locations.py +0 -15
- meerschaum/api/models/_metrics.py +0 -15
- meerschaum/config/_environment.py +0 -145
- meerschaum/config/static/__init__.py +0 -186
- meerschaum-2.9.4.dist-info/RECORD +0 -263
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/top_level.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0.dist-info}/zip-safe +0 -0
meerschaum/utils/sql.py
CHANGED
@@ -41,13 +41,33 @@ version_queries = {
|
|
41
41
|
}
|
42
42
|
SKIP_IF_EXISTS_FLAVORS = {'mssql', 'oracle'}
|
43
43
|
DROP_IF_EXISTS_FLAVORS = {
|
44
|
-
'timescaledb',
|
44
|
+
'timescaledb',
|
45
|
+
'timescaledb-ha',
|
46
|
+
'postgresql',
|
47
|
+
'postgis',
|
48
|
+
'citus',
|
49
|
+
'mssql',
|
50
|
+
'mysql',
|
51
|
+
'mariadb',
|
52
|
+
'sqlite',
|
45
53
|
}
|
46
54
|
DROP_INDEX_IF_EXISTS_FLAVORS = {
|
47
|
-
'mssql',
|
55
|
+
'mssql',
|
56
|
+
'timescaledb',
|
57
|
+
'timescaledb-ha',
|
58
|
+
'postgresql',
|
59
|
+
'postgis',
|
60
|
+
'sqlite',
|
61
|
+
'citus',
|
48
62
|
}
|
49
63
|
SKIP_AUTO_INCREMENT_FLAVORS = {'citus', 'duckdb'}
|
50
|
-
COALESCE_UNIQUE_INDEX_FLAVORS = {
|
64
|
+
COALESCE_UNIQUE_INDEX_FLAVORS = {
|
65
|
+
'timescaledb',
|
66
|
+
'timescaledb-ha',
|
67
|
+
'postgresql',
|
68
|
+
'postgis',
|
69
|
+
'citus',
|
70
|
+
}
|
51
71
|
UPDATE_QUERIES = {
|
52
72
|
'default': """
|
53
73
|
UPDATE {target_table_name} AS f
|
@@ -67,6 +87,12 @@ UPDATE_QUERIES = {
|
|
67
87
|
FROM {patch_table_name}
|
68
88
|
ON CONFLICT ({join_cols_str}) DO {update_or_nothing} {sets_subquery_none_excluded}
|
69
89
|
""",
|
90
|
+
'timescaledb-ha-upsert': """
|
91
|
+
INSERT INTO {target_table_name} ({patch_cols_str})
|
92
|
+
SELECT {patch_cols_str}
|
93
|
+
FROM {patch_table_name}
|
94
|
+
ON CONFLICT ({join_cols_str}) DO {update_or_nothing} {sets_subquery_none_excluded}
|
95
|
+
""",
|
70
96
|
'postgresql-upsert': """
|
71
97
|
INSERT INTO {target_table_name} ({patch_cols_str})
|
72
98
|
SELECT {patch_cols_str}
|
@@ -233,7 +259,7 @@ columns_types_queries = {
|
|
233
259
|
DATA_TYPE AS [type],
|
234
260
|
NUMERIC_PRECISION AS [numeric_precision],
|
235
261
|
NUMERIC_SCALE AS [numeric_scale]
|
236
|
-
FROM {db_prefix}INFORMATION_SCHEMA.COLUMNS
|
262
|
+
FROM {db_prefix}INFORMATION_SCHEMA.COLUMNS WITH (NOLOCK)
|
237
263
|
WHERE TABLE_NAME IN (
|
238
264
|
'{table}',
|
239
265
|
'{table_trunc}'
|
@@ -286,6 +312,7 @@ columns_types_queries = {
|
|
286
312
|
}
|
287
313
|
hypertable_queries = {
|
288
314
|
'timescaledb': 'SELECT hypertable_size(\'{table_name}\')',
|
315
|
+
'timescaledb-ha': 'SELECT hypertable_size(\'{table_name}\')',
|
289
316
|
'citus': 'SELECT citus_table_size(\'{table_name}\')',
|
290
317
|
}
|
291
318
|
columns_indices_queries = {
|
@@ -377,18 +404,18 @@ columns_indices_queries = {
|
|
377
404
|
ELSE CAST(0 AS BIT)
|
378
405
|
END AS [clustered]
|
379
406
|
FROM
|
380
|
-
sys.schemas s
|
381
|
-
INNER JOIN sys.tables t
|
407
|
+
sys.schemas s WITH (NOLOCK)
|
408
|
+
INNER JOIN sys.tables t WITH (NOLOCK)
|
382
409
|
ON s.schema_id = t.schema_id
|
383
|
-
INNER JOIN sys.indexes i
|
410
|
+
INNER JOIN sys.indexes i WITH (NOLOCK)
|
384
411
|
ON t.object_id = i.object_id
|
385
|
-
INNER JOIN sys.index_columns ic
|
412
|
+
INNER JOIN sys.index_columns ic WITH (NOLOCK)
|
386
413
|
ON i.object_id = ic.object_id
|
387
414
|
AND i.index_id = ic.index_id
|
388
|
-
INNER JOIN sys.columns c
|
415
|
+
INNER JOIN sys.columns c WITH (NOLOCK)
|
389
416
|
ON ic.object_id = c.object_id
|
390
417
|
AND ic.column_id = c.column_id
|
391
|
-
LEFT JOIN sys.key_constraints kc
|
418
|
+
LEFT JOIN sys.key_constraints kc WITH (NOLOCK)
|
392
419
|
ON kc.parent_object_id = i.object_id
|
393
420
|
AND kc.type = 'PK'
|
394
421
|
AND kc.name = i.name
|
@@ -483,49 +510,83 @@ reset_autoincrement_queries: Dict[str, Union[str, List[str]]] = {
|
|
483
510
|
),
|
484
511
|
}
|
485
512
|
table_wrappers = {
|
486
|
-
'default'
|
487
|
-
'timescaledb': ('"', '"'),
|
488
|
-
'
|
489
|
-
'
|
490
|
-
'
|
491
|
-
'
|
492
|
-
'
|
493
|
-
'
|
494
|
-
'
|
495
|
-
'
|
496
|
-
'
|
497
|
-
'
|
513
|
+
'default' : ('"', '"'),
|
514
|
+
'timescaledb' : ('"', '"'),
|
515
|
+
'timescaledb-ha': ('"', '"'),
|
516
|
+
'citus' : ('"', '"'),
|
517
|
+
'duckdb' : ('"', '"'),
|
518
|
+
'postgresql' : ('"', '"'),
|
519
|
+
'postgis' : ('"', '"'),
|
520
|
+
'sqlite' : ('"', '"'),
|
521
|
+
'mysql' : ('`', '`'),
|
522
|
+
'mariadb' : ('`', '`'),
|
523
|
+
'mssql' : ('[', ']'),
|
524
|
+
'cockroachdb' : ('"', '"'),
|
525
|
+
'oracle' : ('"', '"'),
|
498
526
|
}
|
499
527
|
max_name_lens = {
|
500
|
-
'default'
|
501
|
-
'mssql'
|
502
|
-
'oracle'
|
503
|
-
'postgresql'
|
504
|
-
'postgis'
|
505
|
-
'timescaledb': 64,
|
506
|
-
'
|
507
|
-
'
|
508
|
-
'
|
509
|
-
'
|
510
|
-
'
|
528
|
+
'default' : 64,
|
529
|
+
'mssql' : 128,
|
530
|
+
'oracle' : 30,
|
531
|
+
'postgresql' : 64,
|
532
|
+
'postgis' : 64,
|
533
|
+
'timescaledb' : 64,
|
534
|
+
'timescaledb-ha': 64,
|
535
|
+
'citus' : 64,
|
536
|
+
'cockroachdb' : 64,
|
537
|
+
'sqlite' : 1024, ### Probably more, but 1024 seems more than reasonable.
|
538
|
+
'mysql' : 64,
|
539
|
+
'mariadb' : 64,
|
540
|
+
}
|
541
|
+
json_flavors = {
|
542
|
+
'postgresql',
|
543
|
+
'postgis',
|
544
|
+
'timescaledb',
|
545
|
+
'timescaledb-ha',
|
546
|
+
'citus',
|
547
|
+
'cockroachdb',
|
548
|
+
}
|
549
|
+
NO_SCHEMA_FLAVORS = {
|
550
|
+
'oracle',
|
551
|
+
'sqlite',
|
552
|
+
'mysql',
|
553
|
+
'mariadb',
|
554
|
+
'duckdb',
|
511
555
|
}
|
512
|
-
json_flavors = {'postgresql', 'postgis', 'timescaledb', 'citus', 'cockroachdb'}
|
513
|
-
NO_SCHEMA_FLAVORS = {'oracle', 'sqlite', 'mysql', 'mariadb', 'duckdb'}
|
514
556
|
DEFAULT_SCHEMA_FLAVORS = {
|
515
557
|
'postgresql': 'public',
|
516
558
|
'postgis': 'public',
|
517
559
|
'timescaledb': 'public',
|
560
|
+
'timescaledb-ha': 'public',
|
518
561
|
'citus': 'public',
|
519
562
|
'cockroachdb': 'public',
|
520
563
|
'mysql': 'mysql',
|
521
564
|
'mariadb': 'mysql',
|
522
565
|
'mssql': 'dbo',
|
523
566
|
}
|
524
|
-
OMIT_NULLSFIRST_FLAVORS = {
|
567
|
+
OMIT_NULLSFIRST_FLAVORS = {
|
568
|
+
'mariadb',
|
569
|
+
'mysql',
|
570
|
+
'mssql',
|
571
|
+
}
|
525
572
|
|
526
|
-
SINGLE_ALTER_TABLE_FLAVORS = {
|
527
|
-
|
528
|
-
|
573
|
+
SINGLE_ALTER_TABLE_FLAVORS = {
|
574
|
+
'duckdb',
|
575
|
+
'sqlite',
|
576
|
+
'mssql',
|
577
|
+
'oracle',
|
578
|
+
}
|
579
|
+
NO_CTE_FLAVORS = {
|
580
|
+
'mysql',
|
581
|
+
'mariadb',
|
582
|
+
}
|
583
|
+
NO_SELECT_INTO_FLAVORS = {
|
584
|
+
'sqlite',
|
585
|
+
'oracle',
|
586
|
+
'mysql',
|
587
|
+
'mariadb',
|
588
|
+
'duckdb',
|
589
|
+
}
|
529
590
|
|
530
591
|
|
531
592
|
def clean(substring: str) -> None:
|
@@ -560,6 +621,7 @@ def dateadd_str(
|
|
560
621
|
- `'postgresql'`
|
561
622
|
- `'postgis'`
|
562
623
|
- `'timescaledb'`
|
624
|
+
- `'timescaledb-ha'`
|
563
625
|
- `'citus'`
|
564
626
|
- `'cockroachdb'`
|
565
627
|
- `'duckdb'`
|
@@ -663,7 +725,14 @@ def dateadd_str(
|
|
663
725
|
)
|
664
726
|
|
665
727
|
da = ""
|
666
|
-
if flavor in (
|
728
|
+
if flavor in (
|
729
|
+
'postgresql',
|
730
|
+
'postgis',
|
731
|
+
'timescaledb',
|
732
|
+
'timescaledb-ha',
|
733
|
+
'cockroachdb',
|
734
|
+
'citus',
|
735
|
+
):
|
667
736
|
begin = (
|
668
737
|
f"CAST({begin} AS {db_type})" if begin != 'now'
|
669
738
|
else f"CAST(NOW() AT TIME ZONE 'utc' AS {db_type})"
|
@@ -831,7 +900,7 @@ def sql_item_name(item: str, flavor: str, schema: Optional[str] = None) -> str:
|
|
831
900
|
### NOTE: System-reserved words must be quoted.
|
832
901
|
if truncated_item.lower() in (
|
833
902
|
'float', 'varchar', 'nvarchar', 'clob',
|
834
|
-
'boolean', 'integer', 'table', 'row',
|
903
|
+
'boolean', 'integer', 'table', 'row', 'date',
|
835
904
|
):
|
836
905
|
wrappers = ('"', '"')
|
837
906
|
else:
|
@@ -969,7 +1038,7 @@ def build_where(
|
|
969
1038
|
```
|
970
1039
|
"""
|
971
1040
|
import json
|
972
|
-
from meerschaum.
|
1041
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
973
1042
|
from meerschaum.utils.warnings import warn
|
974
1043
|
from meerschaum.utils.dtypes import value_is_null, none_if_null
|
975
1044
|
negation_prefix = STATIC_CONFIG['system']['fetch_pipes_keys']['negation_prefix']
|
@@ -1517,6 +1586,8 @@ def get_update_queries(
|
|
1517
1586
|
datetime_col: Optional[str] = None,
|
1518
1587
|
schema: Optional[str] = None,
|
1519
1588
|
patch_schema: Optional[str] = None,
|
1589
|
+
target_cols_types: Optional[Dict[str, str]] = None,
|
1590
|
+
patch_cols_types: Optional[Dict[str, str]] = None,
|
1520
1591
|
identity_insert: bool = False,
|
1521
1592
|
null_indices: bool = True,
|
1522
1593
|
cast_columns: bool = True,
|
@@ -1557,6 +1628,14 @@ def get_update_queries(
|
|
1557
1628
|
If provided, use this schema when quoting the patch table.
|
1558
1629
|
Defaults to `schema`.
|
1559
1630
|
|
1631
|
+
target_cols_types: Optional[Dict[str, Any]], default None
|
1632
|
+
If provided, use these as the columns-types dictionary for the target table.
|
1633
|
+
Default will infer from the database context.
|
1634
|
+
|
1635
|
+
patch_cols_types: Optional[Dict[str, Any]], default None
|
1636
|
+
If provided, use these as the columns-types dictionary for the target table.
|
1637
|
+
Default will infer from the database context.
|
1638
|
+
|
1560
1639
|
identity_insert: bool, default False
|
1561
1640
|
If `True`, include `SET IDENTITY_INSERT` queries before and after the update queries.
|
1562
1641
|
Only applies for MSSQL upserts.
|
@@ -1603,14 +1682,14 @@ def get_update_queries(
|
|
1603
1682
|
flavor=flavor,
|
1604
1683
|
schema=schema,
|
1605
1684
|
debug=debug,
|
1606
|
-
)
|
1685
|
+
) if not target_cols_types else target_cols_types
|
1607
1686
|
patch_table_columns = get_table_cols_types(
|
1608
1687
|
patch,
|
1609
1688
|
connectable,
|
1610
1689
|
flavor=flavor,
|
1611
1690
|
schema=patch_schema,
|
1612
1691
|
debug=debug,
|
1613
|
-
)
|
1692
|
+
) if not patch_cols_types else patch_cols_types
|
1614
1693
|
|
1615
1694
|
patch_cols_str = ', '.join(
|
1616
1695
|
[
|
@@ -1838,10 +1917,9 @@ def get_null_replacement(typ: str, flavor: str) -> str:
|
|
1838
1917
|
A value which may stand in place of NULL for this type.
|
1839
1918
|
`'None'` is returned if a value cannot be determined.
|
1840
1919
|
"""
|
1841
|
-
from meerschaum.utils.dtypes import are_dtypes_equal
|
1842
1920
|
from meerschaum.utils.dtypes.sql import DB_FLAVORS_CAST_DTYPES
|
1843
1921
|
if 'geometry' in typ.lower():
|
1844
|
-
return '010100000000008058346FCDC100008058346FCDC1'
|
1922
|
+
return "'010100000000008058346FCDC100008058346FCDC1'"
|
1845
1923
|
if 'int' in typ.lower() or typ.lower() in ('numeric', 'number'):
|
1846
1924
|
return '-987654321'
|
1847
1925
|
if 'bool' in typ.lower() or typ.lower() == 'bit':
|
@@ -2113,7 +2191,11 @@ def _get_create_table_query_from_dtypes(
|
|
2113
2191
|
)
|
2114
2192
|
elif flavor == 'oracle':
|
2115
2193
|
query += f"\n {col_name} {col_db_type} {auto_increment_str} PRIMARY KEY,"
|
2116
|
-
elif
|
2194
|
+
elif (
|
2195
|
+
flavor in ('timescaledb', 'timescaledb-ha')
|
2196
|
+
and datetime_column
|
2197
|
+
and datetime_column != primary_key
|
2198
|
+
):
|
2117
2199
|
query += f"\n {col_name} {col_db_type}{auto_increment_str} NOT NULL,"
|
2118
2200
|
elif flavor == 'mssql':
|
2119
2201
|
query += f"\n {col_name} {col_db_type}{auto_increment_str} NOT NULL,"
|
@@ -2126,7 +2208,7 @@ def _get_create_table_query_from_dtypes(
|
|
2126
2208
|
col_name = sql_item_name(col, schema=None, flavor=flavor)
|
2127
2209
|
query += f"\n {col_name} {db_type},"
|
2128
2210
|
if (
|
2129
|
-
flavor
|
2211
|
+
flavor in ('timescaledb', 'timescaledb-ha')
|
2130
2212
|
and datetime_column
|
2131
2213
|
and primary_key
|
2132
2214
|
and datetime_column != primary_key
|
@@ -2249,7 +2331,11 @@ def _get_create_table_query_from_cte(
|
|
2249
2331
|
"ADD PRIMARY KEY ({primary_key_name})"
|
2250
2332
|
),
|
2251
2333
|
]
|
2252
|
-
elif
|
2334
|
+
elif (
|
2335
|
+
flavor in ('timescaledb', 'timescaledb-ha')
|
2336
|
+
and datetime_column
|
2337
|
+
and datetime_column != primary_key
|
2338
|
+
):
|
2253
2339
|
create_table_queries = [
|
2254
2340
|
(
|
2255
2341
|
"SELECT *\n"
|
meerschaum/utils/threading.py
CHANGED
@@ -10,6 +10,9 @@ from __future__ import annotations
|
|
10
10
|
from meerschaum.utils.typing import Optional
|
11
11
|
|
12
12
|
import threading
|
13
|
+
import ctypes
|
14
|
+
import signal
|
15
|
+
|
13
16
|
Lock = threading.Lock
|
14
17
|
RLock = threading.RLock
|
15
18
|
Event = threading.Event
|
@@ -54,6 +57,45 @@ class Thread(threading.Thread):
|
|
54
57
|
"""Set the return to the result of the target."""
|
55
58
|
self._return = self._target(*self._args, **self._kwargs)
|
56
59
|
|
60
|
+
def send_signal(self, signalnum):
|
61
|
+
"""
|
62
|
+
Send a signal to the thread.
|
63
|
+
"""
|
64
|
+
if not self.is_alive():
|
65
|
+
return
|
66
|
+
|
67
|
+
if signalnum == signal.SIGINT:
|
68
|
+
self.raise_exception(KeyboardInterrupt())
|
69
|
+
elif signalnum == signal.SIGTERM:
|
70
|
+
self.raise_exception(SystemExit())
|
71
|
+
else:
|
72
|
+
signal.pthread_kill(self.ident, signalnum)
|
73
|
+
|
74
|
+
def raise_exception(self, exc: BaseException):
|
75
|
+
"""
|
76
|
+
Raise an exception in the thread.
|
77
|
+
|
78
|
+
This uses a CPython-specific implementation and is not guaranteed to be stable.
|
79
|
+
It may also be deprecated in future Python versions.
|
80
|
+
"""
|
81
|
+
if not self.is_alive():
|
82
|
+
return
|
83
|
+
|
84
|
+
if not hasattr(ctypes.pythonapi, 'PyThreadState_SetAsyncExc'):
|
85
|
+
return
|
86
|
+
|
87
|
+
exc_class = exc if isinstance(exc, type) else type(exc)
|
88
|
+
|
89
|
+
ident = self.ident
|
90
|
+
if ident is None:
|
91
|
+
return
|
92
|
+
|
93
|
+
ret = ctypes.pythonapi.PyThreadState_SetAsyncExc(
|
94
|
+
ctypes.c_ulong(ident),
|
95
|
+
ctypes.py_object(exc_class)
|
96
|
+
)
|
97
|
+
if ret > 1:
|
98
|
+
ctypes.pythonapi.PyThreadState_SetAsyncExc(ident, 0)
|
57
99
|
|
58
100
|
class Worker(threading.Thread):
|
59
101
|
"""Wrapper for `threading.Thread` for working with `queue.Queue` objects."""
|
meerschaum/utils/typing.py
CHANGED
@@ -76,10 +76,7 @@ import collections.abc
|
|
76
76
|
collections.Iterable = collections.abc.Iterable
|
77
77
|
|
78
78
|
SuccessTuple = Tuple[bool, str]
|
79
|
-
InstanceConnector =
|
80
|
-
'meerschaum.connectors.sql.SQLConnector',
|
81
|
-
'meerschaum.connectors.api.APIConnector'
|
82
|
-
]
|
79
|
+
InstanceConnector = 'meerschaum.connectors.InstanceConnector'
|
83
80
|
PipesDict = Dict[
|
84
81
|
str, Dict[ ### connector_keys : metrics
|
85
82
|
str, Dict[ ### metric_key : locations
|
meerschaum/utils/venv/_Venv.py
CHANGED
@@ -35,13 +35,13 @@ class Venv:
|
|
35
35
|
|
36
36
|
def __init__(
|
37
37
|
self,
|
38
|
-
venv: Union[str, 'meerschaum.
|
38
|
+
venv: Union[str, 'meerschaum.core.Plugin', None] = 'mrsm',
|
39
39
|
debug: bool = False,
|
40
40
|
) -> None:
|
41
41
|
from meerschaum.utils.venv import activate_venv, deactivate_venv, active_venvs
|
42
42
|
### For some weird threading issue,
|
43
43
|
### we can't use `isinstance` here.
|
44
|
-
if '
|
44
|
+
if '_Plugin' in str(type(venv)):
|
45
45
|
self._venv = venv.name
|
46
46
|
self._activate = venv.activate_venv
|
47
47
|
self._deactivate = venv.deactivate_venv
|
@@ -8,6 +8,9 @@ Manage virtual environments.
|
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
10
|
|
11
|
+
import sys
|
12
|
+
import pathlib
|
13
|
+
|
11
14
|
from meerschaum.utils.typing import Optional, Union, Dict, List, Tuple
|
12
15
|
from meerschaum.utils.threading import RLock, get_ident
|
13
16
|
|
@@ -229,7 +232,6 @@ def verify_venv(
|
|
229
232
|
"""
|
230
233
|
Verify that the virtual environment matches the expected state.
|
231
234
|
"""
|
232
|
-
import pathlib
|
233
235
|
import platform
|
234
236
|
import os
|
235
237
|
import shutil
|
@@ -382,11 +384,10 @@ def init_venv(
|
|
382
384
|
import sys
|
383
385
|
import platform
|
384
386
|
import os
|
385
|
-
import pathlib
|
386
387
|
import shutil
|
387
388
|
import time
|
388
389
|
|
389
|
-
from meerschaum.
|
390
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
390
391
|
from meerschaum.config._paths import (
|
391
392
|
VIRTENV_RESOURCES_PATH,
|
392
393
|
VENVS_CACHE_RESOURCES_PATH,
|
@@ -659,6 +660,7 @@ def venv_exec(
|
|
659
660
|
cmd_list,
|
660
661
|
stdout=stdout,
|
661
662
|
stderr=stderr,
|
663
|
+
stdin=sys.stdin,
|
662
664
|
env=env,
|
663
665
|
**group_kwargs
|
664
666
|
)
|
@@ -682,7 +684,7 @@ def venv_target_path(
|
|
682
684
|
venv: Union[str, None],
|
683
685
|
allow_nonexistent: bool = False,
|
684
686
|
debug: bool = False,
|
685
|
-
) ->
|
687
|
+
) -> pathlib.Path:
|
686
688
|
"""
|
687
689
|
Return a virtual environment's site-package path.
|
688
690
|
|
@@ -702,10 +704,9 @@ def venv_target_path(
|
|
702
704
|
import os
|
703
705
|
import sys
|
704
706
|
import platform
|
705
|
-
import pathlib
|
706
707
|
import site
|
707
708
|
from meerschaum.config._paths import VIRTENV_RESOURCES_PATH
|
708
|
-
from meerschaum.
|
709
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
709
710
|
|
710
711
|
### Check sys.path for a user-writable site-packages directory.
|
711
712
|
if venv is None:
|
@@ -839,7 +840,6 @@ def get_module_venv(module) -> Union[str, None]:
|
|
839
840
|
-------
|
840
841
|
The name of a venv or `None`.
|
841
842
|
"""
|
842
|
-
import pathlib
|
843
843
|
from meerschaum.config.paths import VIRTENV_RESOURCES_PATH
|
844
844
|
module_path = pathlib.Path(module.__file__).resolve()
|
845
845
|
try:
|
meerschaum/utils/warnings.py
CHANGED
@@ -100,11 +100,11 @@ def warn(*args, stacklevel=2, stack=True, color: bool = True, **kw) -> None:
|
|
100
100
|
|
101
101
|
|
102
102
|
def exception_with_traceback(
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
103
|
+
message: str,
|
104
|
+
exception_class = Exception,
|
105
|
+
stacklevel = 1,
|
106
|
+
tb_type = 'single'
|
107
|
+
):
|
108
108
|
"""Traceback construction help found here:
|
109
109
|
https://stackoverflow.com/questions/27138440/how-to-create-a-traceback-object
|
110
110
|
"""
|
@@ -165,12 +165,16 @@ def error(
|
|
165
165
|
Raise an exception with supressed traceback.
|
166
166
|
"""
|
167
167
|
from meerschaum.utils.formatting import (
|
168
|
-
CHARSET,
|
168
|
+
CHARSET,
|
169
|
+
ANSI,
|
170
|
+
get_console,
|
171
|
+
fill_ansi,
|
172
|
+
highlight_pipes,
|
173
|
+
_init,
|
169
174
|
)
|
170
175
|
from meerschaum.utils.packages import import_rich, attempt_import
|
171
176
|
from meerschaum.config import get_config
|
172
|
-
|
173
|
-
rich = import_rich()
|
177
|
+
_ = import_rich()
|
174
178
|
rich_traceback = attempt_import('rich.traceback')
|
175
179
|
error_config = get_config('formatting', 'errors', patch=True)
|
176
180
|
message = ' ' + error_config[CHARSET]['icon'] + ' ' + str(message)
|
@@ -186,23 +190,25 @@ def error(
|
|
186
190
|
exception_class, exception, exception.__traceback__
|
187
191
|
)
|
188
192
|
rtb = rich_traceback.Traceback(trace)
|
189
|
-
except Exception
|
193
|
+
except Exception:
|
190
194
|
trace, rtb = None, None
|
191
195
|
if trace is None or rtb is None:
|
192
196
|
nopretty = True
|
193
197
|
if not nopretty and stack:
|
194
198
|
if get_console() is not None:
|
195
199
|
get_console().print(rtb)
|
196
|
-
frame = sys._getframe(len(inspect.stack()) - 1)
|
197
200
|
if raise_:
|
198
201
|
raise color_exception
|
199
202
|
|
200
203
|
|
201
204
|
def info(message: str, icon: bool = True, **kw):
|
202
205
|
"""Print an informative message."""
|
203
|
-
from meerschaum.utils.packages import import_rich, attempt_import
|
204
206
|
from meerschaum.utils.formatting import (
|
205
|
-
CHARSET,
|
207
|
+
CHARSET,
|
208
|
+
ANSI,
|
209
|
+
highlight_pipes,
|
210
|
+
fill_ansi,
|
211
|
+
_init,
|
206
212
|
)
|
207
213
|
from meerschaum.config import get_config
|
208
214
|
info_config = get_config('formatting', 'info', patch=True)
|
@@ -215,4 +221,4 @@ def info(message: str, icon: bool = True, **kw):
|
|
215
221
|
message = fill_ansi(lines[0], **info_config['ansi']['rich']) + (
|
216
222
|
'\n' + '\n'.join(lines[1:]) if len(lines) > 1 else ''
|
217
223
|
)
|
218
|
-
print(message)
|
224
|
+
print(message, flush=True)
|