ygo 1.0.9__tar.gz → 1.0.10__tar.gz
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.
Potentially problematic release.
This version of ygo might be problematic. Click here for more details.
- {ygo-1.0.9/ygo.egg-info → ygo-1.0.10}/PKG-INFO +7 -2
- {ygo-1.0.9 → ygo-1.0.10}/pyproject.toml +8 -3
- {ygo-1.0.9 → ygo-1.0.10}/ycat/__init__.py +7 -8
- ygo-1.0.10/ycat/client.py +172 -0
- {ygo-1.0.9 → ygo-1.0.10}/ycat/parse.py +0 -2
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/__init__.py +1 -0
- ygo-1.0.10/ycat/updator.py +101 -0
- ygo-1.0.10/ygo/__init__.py +34 -0
- {ygo-1.0.9 → ygo-1.0.10}/ygo/exceptions.py +17 -1
- {ygo-1.0.9 → ygo-1.0.10}/ygo/ygo.py +3 -15
- {ygo-1.0.9 → ygo-1.0.10/ygo.egg-info}/PKG-INFO +7 -2
- {ygo-1.0.9 → ygo-1.0.10}/ygo.egg-info/SOURCES.txt +11 -12
- {ygo-1.0.9 → ygo-1.0.10}/ygo.egg-info/requires.txt +5 -0
- {ygo-1.0.9 → ygo-1.0.10}/ygo.egg-info/top_level.txt +0 -1
- {ygo-1.0.9 → ygo-1.0.10}/ylog/__init__.py +3 -2
- {ygo-1.0.9 → ygo-1.0.10}/ylog/core.py +61 -28
- ygo-1.0.9/ycat/client.py +0 -145
- ygo-1.0.9/ycat/dtype.py +0 -389
- ygo-1.0.9/ycat/yck.py +0 -87
- ygo-1.0.9/ygo/__init__.py +0 -10
- {ygo-1.0.9 → ygo-1.0.10}/LICENSE +0 -0
- {ygo-1.0.9 → ygo-1.0.10}/README.md +0 -0
- {ygo-1.0.9 → ygo-1.0.10}/setup.cfg +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/errors.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/expr.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/qdf.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/udf/__init__.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/udf/base_udf.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/udf/cs_udf.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/udf/d_udf.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/udf/ind_udf.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10/ycat}/qdf/udf/ts_udf.py +0 -0
- {ygo-1.0.9 → ygo-1.0.10}/ygo.egg-info/dependency_links.txt +0 -0
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ygo
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.10
|
|
4
4
|
Project-URL: homepage, https://github.com/link-yundi/ygo
|
|
5
5
|
Project-URL: repository, https://github.com/link-yundi/ygo
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
|
+
Requires-Dist: clickhouse-df>=0.1.5
|
|
9
10
|
Requires-Dist: clickhouse-driver>=0.2.9
|
|
11
|
+
Requires-Dist: connectorx>=0.3.3
|
|
10
12
|
Requires-Dist: dynaconf>=3.2.11
|
|
11
13
|
Requires-Dist: exchange-calendars>=4.2.8
|
|
12
14
|
Requires-Dist: joblib>=1.4.2
|
|
13
15
|
Requires-Dist: lark>=1.2.2
|
|
16
|
+
Requires-Dist: lightgbm>=4.6.0
|
|
14
17
|
Requires-Dist: loguru>=0.7.3
|
|
18
|
+
Requires-Dist: mlflow>=2.17.2
|
|
15
19
|
Requires-Dist: pandas>=2.0.3
|
|
16
20
|
Requires-Dist: polars>=1.8.2
|
|
17
21
|
Requires-Dist: pyarrow>=17.0.0
|
|
@@ -19,6 +23,7 @@ Requires-Dist: pymysql>=1.1.1
|
|
|
19
23
|
Requires-Dist: sqlalchemy>=2.0.40
|
|
20
24
|
Requires-Dist: sqlparse>=0.5.3
|
|
21
25
|
Requires-Dist: toolz>=1.0.0
|
|
26
|
+
Requires-Dist: torch>=2.5.1
|
|
22
27
|
Requires-Dist: tqdm>=4.67.1
|
|
23
28
|
Dynamic: license-file
|
|
24
29
|
|
|
@@ -4,17 +4,21 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ygo"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.10"
|
|
8
8
|
description = ""
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
11
|
dependencies = [
|
|
12
|
+
"clickhouse-df>=0.1.5",
|
|
12
13
|
"clickhouse-driver>=0.2.9",
|
|
14
|
+
"connectorx>=0.3.3",
|
|
13
15
|
"dynaconf>=3.2.11",
|
|
14
16
|
"exchange-calendars>=4.2.8",
|
|
15
17
|
"joblib>=1.4.2",
|
|
16
18
|
"lark>=1.2.2",
|
|
19
|
+
"lightgbm>=4.6.0",
|
|
17
20
|
"loguru>=0.7.3",
|
|
21
|
+
"mlflow>=2.17.2",
|
|
18
22
|
"pandas>=2.0.3",
|
|
19
23
|
"polars>=1.8.2",
|
|
20
24
|
"pyarrow>=17.0.0",
|
|
@@ -22,12 +26,13 @@ dependencies = [
|
|
|
22
26
|
"sqlalchemy>=2.0.40",
|
|
23
27
|
"sqlparse>=0.5.3",
|
|
24
28
|
"toolz>=1.0.0",
|
|
29
|
+
"torch>=2.5.1",
|
|
25
30
|
"tqdm>=4.67.1",
|
|
26
31
|
]
|
|
27
32
|
|
|
28
33
|
[tool.setuptools.packages.find]
|
|
29
34
|
where = ["."]
|
|
30
|
-
include = ["ygo", "ygo.*", "ylog", "ylog.*", "ycat", "ycat.*",
|
|
35
|
+
include = ["ygo", "ygo.*", "ylog", "ylog.*", "ycat", "ycat.*",]
|
|
31
36
|
|
|
32
37
|
[project.urls]
|
|
33
38
|
homepage = "https://github.com/link-yundi/ygo"
|
|
@@ -13,12 +13,12 @@ from .client import (
|
|
|
13
13
|
get_settings,
|
|
14
14
|
sql,
|
|
15
15
|
put,
|
|
16
|
-
create_engine_ck,
|
|
17
|
-
create_engine_mysql,
|
|
18
|
-
read_mysql,
|
|
19
|
-
read_ck,
|
|
20
16
|
tb_path,
|
|
17
|
+
read_ck,
|
|
18
|
+
read_mysql,
|
|
21
19
|
)
|
|
20
|
+
from .qdf import from_polars
|
|
21
|
+
from .updator import Updator
|
|
22
22
|
|
|
23
23
|
__all__ = [
|
|
24
24
|
"HOME",
|
|
@@ -26,9 +26,8 @@ __all__ = [
|
|
|
26
26
|
"get_settings",
|
|
27
27
|
"sql",
|
|
28
28
|
"put",
|
|
29
|
-
"create_engine_ck",
|
|
30
|
-
"create_engine_mysql",
|
|
31
|
-
"read_mysql",
|
|
32
|
-
"read_ck",
|
|
33
29
|
"tb_path",
|
|
30
|
+
"read_ck",
|
|
31
|
+
"read_mysql",
|
|
32
|
+
"Updator",
|
|
34
33
|
]
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
---------------------------------------------
|
|
4
|
+
Created on 2024/7/1 09:44
|
|
5
|
+
@author: ZhangYundi
|
|
6
|
+
@email: yundi.xxii@outlook.com
|
|
7
|
+
---------------------------------------------
|
|
8
|
+
"""
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
import urllib
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
import clickhouse_df
|
|
15
|
+
import polars as pl
|
|
16
|
+
from dynaconf import Dynaconf
|
|
17
|
+
|
|
18
|
+
import ylog
|
|
19
|
+
from .parse import extract_table_names_from_sql
|
|
20
|
+
|
|
21
|
+
# 配置文件在 “~/.catdb/setting.toml”
|
|
22
|
+
USERHOME = os.path.expanduser('~') # 用户家目录
|
|
23
|
+
NAME = "catdb"
|
|
24
|
+
CONFIG_PATH = os.path.join(USERHOME, f".{NAME}", "settings.toml")
|
|
25
|
+
if not os.path.exists(CONFIG_PATH):
|
|
26
|
+
try:
|
|
27
|
+
os.makedirs(os.path.dirname(CONFIG_PATH))
|
|
28
|
+
except FileExistsError as e:
|
|
29
|
+
...
|
|
30
|
+
except Exception as e:
|
|
31
|
+
ylog.error(f"配置文件生成失败: {e}")
|
|
32
|
+
catdb_path = os.path.join(USERHOME, NAME)
|
|
33
|
+
template_content = f"""[paths]
|
|
34
|
+
{NAME}="{catdb_path}" # 本地数据库,默认家目录
|
|
35
|
+
|
|
36
|
+
## 数据库配置:
|
|
37
|
+
[database]
|
|
38
|
+
[database.ck]
|
|
39
|
+
# urls=["<host1>:<port1>", "<host2>:<port2>",]
|
|
40
|
+
# user="xxx"
|
|
41
|
+
# password="xxxxxx"
|
|
42
|
+
[database.jy]
|
|
43
|
+
# url="<host>:<port>"
|
|
44
|
+
# user="xxxx"
|
|
45
|
+
# password="xxxxxx"
|
|
46
|
+
|
|
47
|
+
## 视情况自由增加其他配置
|
|
48
|
+
"""
|
|
49
|
+
with open(CONFIG_PATH, "w") as f:
|
|
50
|
+
f.write(template_content)
|
|
51
|
+
ylog.info(f"生成配置文件: {CONFIG_PATH}")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_settings():
|
|
55
|
+
try:
|
|
56
|
+
return Dynaconf(settings_files=[CONFIG_PATH])
|
|
57
|
+
except Exception as e:
|
|
58
|
+
ylog.error(f"读取配置文件失败: {e}")
|
|
59
|
+
return {}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
HOME = USERHOME
|
|
63
|
+
CATDB = os.path.join(HOME, NAME)
|
|
64
|
+
# 读取配置文件覆盖
|
|
65
|
+
SETTINGS = get_settings()
|
|
66
|
+
if SETTINGS is not None:
|
|
67
|
+
CATDB = SETTINGS["PATHS"][NAME]
|
|
68
|
+
if not CATDB.endswith(NAME):
|
|
69
|
+
CATDB = os.path.join(CATDB, NAME)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# ======================== 本地数据库 catdb ========================
|
|
73
|
+
def tb_path(tb_name: str) -> Path:
|
|
74
|
+
"""
|
|
75
|
+
返回指定表名 完整的本地路径
|
|
76
|
+
Parameters
|
|
77
|
+
----------
|
|
78
|
+
tb_name: str
|
|
79
|
+
表名,路径写法: a/b/c
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
full_abs_path: pathlib.Path
|
|
83
|
+
完整的本地绝对路径 $HOME/catdb/a/b/c
|
|
84
|
+
"""
|
|
85
|
+
return Path(CATDB, tb_name)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def put(df: pl.DataFrame, tb_name: str, partitions: list[str] | None = None, abs_path: bool = False):
|
|
89
|
+
if not abs_path:
|
|
90
|
+
tbpath = tb_path(tb_name)
|
|
91
|
+
else:
|
|
92
|
+
tbpath = tb_name
|
|
93
|
+
if not tbpath.exists():
|
|
94
|
+
os.makedirs(tbpath, exist_ok=True)
|
|
95
|
+
if partitions is not None:
|
|
96
|
+
df.write_parquet(tbpath, partition_by=partitions)
|
|
97
|
+
else:
|
|
98
|
+
df.write_parquet(tbpath / "data.parquet")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def sql(query: str, abs_path: bool = False, lazy: bool = True):
|
|
102
|
+
tbs = extract_table_names_from_sql(query)
|
|
103
|
+
convertor = dict()
|
|
104
|
+
for tb in tbs:
|
|
105
|
+
if not abs_path:
|
|
106
|
+
db_path = tb_path(tb)
|
|
107
|
+
else:
|
|
108
|
+
db_path = tb
|
|
109
|
+
format_tb = f"read_parquet('{db_path}/**/*.parquet')"
|
|
110
|
+
convertor[tb] = format_tb
|
|
111
|
+
pattern = re.compile("|".join(re.escape(k) for k in convertor.keys()))
|
|
112
|
+
new_query = pattern.sub(lambda m: convertor[m.group(0)], query)
|
|
113
|
+
if not lazy:
|
|
114
|
+
return pl.sql(new_query).collect()
|
|
115
|
+
return pl.sql(new_query)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def read_mysql(query: str, db_conf: str = "database.mysql") -> pl.DataFrame:
|
|
119
|
+
"""
|
|
120
|
+
读取 mysql 返回 polars.DataFrame
|
|
121
|
+
:param query:
|
|
122
|
+
:param db_conf: .catdb/settings.toml 中的 database 配置
|
|
123
|
+
:return: polars.DataFrame
|
|
124
|
+
"""
|
|
125
|
+
try:
|
|
126
|
+
db_setting = get_settings().get(db_conf, {})
|
|
127
|
+
if not isinstance(db_setting, dict):
|
|
128
|
+
raise ValueError(f"Database configuration '{db_conf}' is not a dictionary.")
|
|
129
|
+
|
|
130
|
+
required_keys = ['user', 'password', 'url']
|
|
131
|
+
missing_keys = [key for key in required_keys if key not in db_setting]
|
|
132
|
+
if missing_keys:
|
|
133
|
+
raise KeyError(f"Missing required keys in database config: {missing_keys}")
|
|
134
|
+
|
|
135
|
+
user = urllib.parse.quote_plus(db_setting['user'])
|
|
136
|
+
password = urllib.parse.quote_plus(db_setting['password'])
|
|
137
|
+
uri = f"mysql://{user}:{password}@{db_setting['url']}"
|
|
138
|
+
return pl.read_database_uri(query, uri)
|
|
139
|
+
|
|
140
|
+
except KeyError as e:
|
|
141
|
+
raise RuntimeError("Database configuration error: missing required fields.") from e
|
|
142
|
+
except Exception as e:
|
|
143
|
+
raise RuntimeError(f"Failed to execute MySQL query: {e}") from e
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def read_ck(query: str, db_conf: str = "database.ck") -> pl.DataFrame:
|
|
147
|
+
"""
|
|
148
|
+
读取 clickhouse 集群 返回 polars.DataFrame
|
|
149
|
+
:param query:
|
|
150
|
+
:param db_conf: .catdb/settings.toml 中的 database 配置
|
|
151
|
+
:return: polars.DataFrame
|
|
152
|
+
"""
|
|
153
|
+
try:
|
|
154
|
+
db_setting = get_settings().get(db_conf, {})
|
|
155
|
+
if not isinstance(db_setting, dict):
|
|
156
|
+
raise ValueError(f"Database configuration '{db_conf}' is not a dictionary.")
|
|
157
|
+
|
|
158
|
+
required_keys = ['user', 'password', 'urls']
|
|
159
|
+
missing_keys = [key for key in required_keys if key not in db_setting]
|
|
160
|
+
if missing_keys:
|
|
161
|
+
raise KeyError(f"Missing required keys in database config: {missing_keys}")
|
|
162
|
+
|
|
163
|
+
user = urllib.parse.quote_plus(db_setting['user'])
|
|
164
|
+
password = urllib.parse.quote_plus(db_setting['password'])
|
|
165
|
+
|
|
166
|
+
with clickhouse_df.connect(db_setting['urls'], user=user, password=password):
|
|
167
|
+
return clickhouse_df.to_polars(query)
|
|
168
|
+
|
|
169
|
+
except KeyError as e:
|
|
170
|
+
raise RuntimeError("Database configuration error: missing required fields.") from e
|
|
171
|
+
except Exception as e:
|
|
172
|
+
raise RuntimeError(f"Failed to execute ClickHouse query: {e}") from e
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
---------------------------------------------
|
|
4
|
+
Created on 2025/5/23 01:34
|
|
5
|
+
@author: ZhangYundi
|
|
6
|
+
@email: yundi.xxii@outlook.com
|
|
7
|
+
---------------------------------------------
|
|
8
|
+
"""
|
|
9
|
+
import os
|
|
10
|
+
from datetime import datetime, timedelta
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import ygo
|
|
14
|
+
import ylog
|
|
15
|
+
from .client import CATDB
|
|
16
|
+
|
|
17
|
+
DATE_FORMAT = "%Y-%m-%d"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Updator:
|
|
21
|
+
"""
|
|
22
|
+
数据更新器
|
|
23
|
+
路径:{ycat.CATDB}/updator/{name}
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, name: str, update_time="16:30"):
|
|
27
|
+
"""
|
|
28
|
+
数据更新器
|
|
29
|
+
:param name: 数据更新器名称
|
|
30
|
+
:param update_time: 数据更新时间,默认16:30
|
|
31
|
+
"""
|
|
32
|
+
self.name = name
|
|
33
|
+
self._tb_path = Path(CATDB) / "updator" / name
|
|
34
|
+
os.makedirs(self._tb_path, exist_ok=True)
|
|
35
|
+
self._update_time = update_time
|
|
36
|
+
self.present = datetime.now().today()
|
|
37
|
+
|
|
38
|
+
if self.present.strftime("%H:%M") >= self._update_time:
|
|
39
|
+
self.last_date = self.present.strftime(DATE_FORMAT)
|
|
40
|
+
else:
|
|
41
|
+
self.last_date = (self.present - timedelta(days=1)).strftime(DATE_FORMAT)
|
|
42
|
+
|
|
43
|
+
self._tasks = list()
|
|
44
|
+
self._last_run_file = self._tb_path / f".last_run"
|
|
45
|
+
self.logger = ylog.get_logger("updator")
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def last_update_date(self):
|
|
49
|
+
return self._read_last_run_date()
|
|
50
|
+
|
|
51
|
+
def _read_last_run_date(self):
|
|
52
|
+
if self._last_run_file.exists():
|
|
53
|
+
with open(self._last_run_file, "r") as f:
|
|
54
|
+
return f.read().strip()
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
def _write_last_run_date(self, date_str: str):
|
|
58
|
+
with open(self._last_run_file, "w") as f:
|
|
59
|
+
f.write(date_str)
|
|
60
|
+
|
|
61
|
+
def wrap_fn(self, task_name: str, update_fn: callable):
|
|
62
|
+
"""包装函数,添加异常处理"""
|
|
63
|
+
try:
|
|
64
|
+
update_fn()
|
|
65
|
+
return 0
|
|
66
|
+
except Exception as e:
|
|
67
|
+
self.logger.error(ygo.FailTaskError(task_name=task_name, error=e))
|
|
68
|
+
return 1
|
|
69
|
+
|
|
70
|
+
def add_task(self, task_name: str, update_fn: callable):
|
|
71
|
+
"""添加任务"""
|
|
72
|
+
self._tasks.append((task_name, ygo.delay(self.wrap_fn)(task_name=task_name, update_fn=update_fn)))
|
|
73
|
+
|
|
74
|
+
def do(self,
|
|
75
|
+
overwrite: bool = False,
|
|
76
|
+
n_jobs: int = 10,
|
|
77
|
+
backend: str = "threading"):
|
|
78
|
+
"""
|
|
79
|
+
执行任务
|
|
80
|
+
:param overwrite: 是否覆盖现有数据
|
|
81
|
+
:param n_jobs: 并发数
|
|
82
|
+
:param backend: loky/threading/multiprocessing
|
|
83
|
+
:return:
|
|
84
|
+
"""
|
|
85
|
+
if not overwrite:
|
|
86
|
+
local_last_date = self._read_last_run_date()
|
|
87
|
+
if local_last_date is not None:
|
|
88
|
+
if local_last_date >= self.last_date:
|
|
89
|
+
self.logger.info(f"[{self.name}] 已是最新数据,跳过更新")
|
|
90
|
+
return
|
|
91
|
+
self.logger.info(f"[{self.name}] 更新数据")
|
|
92
|
+
failed_num = 0
|
|
93
|
+
with ygo.pool(n_jobs=n_jobs, backend=backend) as go:
|
|
94
|
+
for task_name, task in self._tasks:
|
|
95
|
+
go.submit(task, job_name=task_name)()
|
|
96
|
+
for status in go.do():
|
|
97
|
+
failed_num += status
|
|
98
|
+
if failed_num < 1:
|
|
99
|
+
self._write_last_run_date(self.last_date)
|
|
100
|
+
self.logger.info(f"[{self.name}] 更新成功,最新数据日期:{self.last_date}")
|
|
101
|
+
self.logger.info(f"[{self.name}] 更新完成,失败任务数:{str(failed_num).zfill(2)}/{str(len(self._tasks)).zfill(2)}")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
---------------------------------------------
|
|
4
|
+
Created on 2025/4/28 15:25
|
|
5
|
+
@author: ZhangYundi
|
|
6
|
+
@email: yundi.xxii@outlook.com
|
|
7
|
+
---------------------------------------------
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .exceptions import FailTaskError
|
|
11
|
+
from .ygo import (
|
|
12
|
+
delay,
|
|
13
|
+
fn_params,
|
|
14
|
+
fn_signature_params,
|
|
15
|
+
fn_path,
|
|
16
|
+
fn_code,
|
|
17
|
+
fn_info,
|
|
18
|
+
module_from_str,
|
|
19
|
+
fn_from_str,
|
|
20
|
+
pool,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"FailTaskError",
|
|
25
|
+
"delay",
|
|
26
|
+
"fn_params",
|
|
27
|
+
"fn_signature_params",
|
|
28
|
+
"fn_path",
|
|
29
|
+
"fn_code",
|
|
30
|
+
"fn_info",
|
|
31
|
+
"fn_from_str",
|
|
32
|
+
"module_from_str",
|
|
33
|
+
"pool"
|
|
34
|
+
]
|
|
@@ -7,7 +7,23 @@ Created on 2024/12/18 下午7:01
|
|
|
7
7
|
---------------------------------------------
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
10
12
|
class WarnException(Exception):
|
|
11
13
|
"""自定义异常类,仅用于警告"""
|
|
12
14
|
def __init__(self, message):
|
|
13
|
-
super().__init__(message) # 调用父类的构造函数
|
|
15
|
+
super().__init__(message) # 调用父类的构造函数
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class FailTaskError:
|
|
19
|
+
task_name: str
|
|
20
|
+
error: Exception
|
|
21
|
+
|
|
22
|
+
def __str__(self):
|
|
23
|
+
return f"""
|
|
24
|
+
[失败任务]: {self.task_name}
|
|
25
|
+
[错误信息]: \n{self.error}
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __repr__(self):
|
|
29
|
+
return self.__str__()
|
|
@@ -18,7 +18,7 @@ from pathlib import Path
|
|
|
18
18
|
from joblib import Parallel, delayed
|
|
19
19
|
|
|
20
20
|
import ylog
|
|
21
|
-
from .exceptions import WarnException
|
|
21
|
+
from .exceptions import WarnException, FailTaskError
|
|
22
22
|
|
|
23
23
|
with warnings.catch_warnings():
|
|
24
24
|
warnings.simplefilter("ignore")
|
|
@@ -228,22 +228,10 @@ def run_job(job, task_id, queue):
|
|
|
228
228
|
try:
|
|
229
229
|
result = job()
|
|
230
230
|
except WarnException as e:
|
|
231
|
-
|
|
232
|
-
=============================================================
|
|
233
|
-
{job.task_name}: {job.task_id}
|
|
234
|
-
{e}
|
|
235
|
-
=============================================================
|
|
236
|
-
"""
|
|
237
|
-
ylog.warning(warn_msg)
|
|
231
|
+
ylog.warning(FailTaskError(task_name=job.task_name, error=e))
|
|
238
232
|
result = None
|
|
239
233
|
except Exception as e:
|
|
240
|
-
|
|
241
|
-
=============================================================
|
|
242
|
-
{job.task_name}: {job.task_id}
|
|
243
|
-
{e}
|
|
244
|
-
=============================================================
|
|
245
|
-
"""
|
|
246
|
-
ylog.error(error_msg)
|
|
234
|
+
ylog.error(FailTaskError(task_name=job.task_name, error=e))
|
|
247
235
|
result = None
|
|
248
236
|
queue.put((task_id, 1))
|
|
249
237
|
return result
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ygo
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.10
|
|
4
4
|
Project-URL: homepage, https://github.com/link-yundi/ygo
|
|
5
5
|
Project-URL: repository, https://github.com/link-yundi/ygo
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
|
+
Requires-Dist: clickhouse-df>=0.1.5
|
|
9
10
|
Requires-Dist: clickhouse-driver>=0.2.9
|
|
11
|
+
Requires-Dist: connectorx>=0.3.3
|
|
10
12
|
Requires-Dist: dynaconf>=3.2.11
|
|
11
13
|
Requires-Dist: exchange-calendars>=4.2.8
|
|
12
14
|
Requires-Dist: joblib>=1.4.2
|
|
13
15
|
Requires-Dist: lark>=1.2.2
|
|
16
|
+
Requires-Dist: lightgbm>=4.6.0
|
|
14
17
|
Requires-Dist: loguru>=0.7.3
|
|
18
|
+
Requires-Dist: mlflow>=2.17.2
|
|
15
19
|
Requires-Dist: pandas>=2.0.3
|
|
16
20
|
Requires-Dist: polars>=1.8.2
|
|
17
21
|
Requires-Dist: pyarrow>=17.0.0
|
|
@@ -19,6 +23,7 @@ Requires-Dist: pymysql>=1.1.1
|
|
|
19
23
|
Requires-Dist: sqlalchemy>=2.0.40
|
|
20
24
|
Requires-Dist: sqlparse>=0.5.3
|
|
21
25
|
Requires-Dist: toolz>=1.0.0
|
|
26
|
+
Requires-Dist: torch>=2.5.1
|
|
22
27
|
Requires-Dist: tqdm>=4.67.1
|
|
23
28
|
Dynamic: license-file
|
|
24
29
|
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
README.md
|
|
3
3
|
pyproject.toml
|
|
4
|
-
qdf/__init__.py
|
|
5
|
-
qdf/errors.py
|
|
6
|
-
qdf/expr.py
|
|
7
|
-
qdf/qdf.py
|
|
8
|
-
qdf/udf/__init__.py
|
|
9
|
-
qdf/udf/base_udf.py
|
|
10
|
-
qdf/udf/cs_udf.py
|
|
11
|
-
qdf/udf/d_udf.py
|
|
12
|
-
qdf/udf/ind_udf.py
|
|
13
|
-
qdf/udf/ts_udf.py
|
|
14
4
|
ycat/__init__.py
|
|
15
5
|
ycat/client.py
|
|
16
|
-
ycat/dtype.py
|
|
17
6
|
ycat/parse.py
|
|
18
|
-
ycat/
|
|
7
|
+
ycat/updator.py
|
|
8
|
+
ycat/qdf/__init__.py
|
|
9
|
+
ycat/qdf/errors.py
|
|
10
|
+
ycat/qdf/expr.py
|
|
11
|
+
ycat/qdf/qdf.py
|
|
12
|
+
ycat/qdf/udf/__init__.py
|
|
13
|
+
ycat/qdf/udf/base_udf.py
|
|
14
|
+
ycat/qdf/udf/cs_udf.py
|
|
15
|
+
ycat/qdf/udf/d_udf.py
|
|
16
|
+
ycat/qdf/udf/ind_udf.py
|
|
17
|
+
ycat/qdf/udf/ts_udf.py
|
|
19
18
|
ygo/__init__.py
|
|
20
19
|
ygo/exceptions.py
|
|
21
20
|
ygo/ygo.py
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
clickhouse-df>=0.1.5
|
|
1
2
|
clickhouse-driver>=0.2.9
|
|
3
|
+
connectorx>=0.3.3
|
|
2
4
|
dynaconf>=3.2.11
|
|
3
5
|
exchange-calendars>=4.2.8
|
|
4
6
|
joblib>=1.4.2
|
|
5
7
|
lark>=1.2.2
|
|
8
|
+
lightgbm>=4.6.0
|
|
6
9
|
loguru>=0.7.3
|
|
10
|
+
mlflow>=2.17.2
|
|
7
11
|
pandas>=2.0.3
|
|
8
12
|
polars>=1.8.2
|
|
9
13
|
pyarrow>=17.0.0
|
|
@@ -11,4 +15,5 @@ pymysql>=1.1.1
|
|
|
11
15
|
sqlalchemy>=2.0.40
|
|
12
16
|
sqlparse>=0.5.3
|
|
13
17
|
toolz>=1.0.0
|
|
18
|
+
torch>=2.5.1
|
|
14
19
|
tqdm>=4.67.1
|
|
@@ -7,7 +7,7 @@ Created on 2025/5/14 15:37
|
|
|
7
7
|
---------------------------------------------
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
from .core import trace, debug, info, warning, error, critical, update_config
|
|
10
|
+
from .core import trace, debug, info, warning, error, critical, update_config, get_logger
|
|
11
11
|
|
|
12
12
|
__all__ = [
|
|
13
13
|
"trace",
|
|
@@ -16,5 +16,6 @@ __all__ = [
|
|
|
16
16
|
"warning",
|
|
17
17
|
"error",
|
|
18
18
|
"critical",
|
|
19
|
-
"update_config"
|
|
19
|
+
"update_config",
|
|
20
|
+
"get_logger",
|
|
20
21
|
]
|