mdbq 4.0.36__py3-none-any.whl → 4.0.38__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.
- mdbq/__version__.py +1 -1
- mdbq/mysql/uploader.py +69 -0
- mdbq/other/error_handler.py +14 -6
- {mdbq-4.0.36.dist-info → mdbq-4.0.38.dist-info}/METADATA +1 -1
- {mdbq-4.0.36.dist-info → mdbq-4.0.38.dist-info}/RECORD +7 -7
- {mdbq-4.0.36.dist-info → mdbq-4.0.38.dist-info}/WHEEL +0 -0
- {mdbq-4.0.36.dist-info → mdbq-4.0.38.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION = '4.0.
|
1
|
+
VERSION = '4.0.38'
|
mdbq/mysql/uploader.py
CHANGED
@@ -1753,6 +1753,75 @@ class MySQLUploader:
|
|
1753
1753
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
1754
1754
|
self.close()
|
1755
1755
|
|
1756
|
+
# @_execute_with_retry
|
1757
|
+
def execute_query(self, sql: str, params: Optional[Tuple] = None) -> List[Dict]:
|
1758
|
+
"""
|
1759
|
+
执行查询SQL语句并返回结果
|
1760
|
+
|
1761
|
+
:param sql: SQL查询语句
|
1762
|
+
:param params: SQL参数,可选
|
1763
|
+
:return: 查询结果列表,每个元素为字典格式
|
1764
|
+
:raises: 可能抛出数据库相关异常
|
1765
|
+
"""
|
1766
|
+
if not sql or not isinstance(sql, str):
|
1767
|
+
logger.error('无效的SQL语句', {'sql': sql})
|
1768
|
+
raise ValueError('SQL语句不能为空且必须是字符串')
|
1769
|
+
|
1770
|
+
try:
|
1771
|
+
with self._get_connection() as conn:
|
1772
|
+
with conn.cursor() as cursor:
|
1773
|
+
cursor.execute(sql, params)
|
1774
|
+
results = cursor.fetchall()
|
1775
|
+
logger.debug('查询执行成功', {
|
1776
|
+
'sql': self._shorten_for_log(sql, 100),
|
1777
|
+
'params': self._shorten_for_log(params, 50),
|
1778
|
+
'结果数量': len(results)
|
1779
|
+
})
|
1780
|
+
return results
|
1781
|
+
except Exception as e:
|
1782
|
+
logger.error('执行查询时出错', {
|
1783
|
+
'sql': self._shorten_for_log(sql, 100),
|
1784
|
+
'params': self._shorten_for_log(params, 50),
|
1785
|
+
'error': str(e)
|
1786
|
+
})
|
1787
|
+
raise
|
1788
|
+
|
1789
|
+
# @_execute_with_retry
|
1790
|
+
def execute_update(self, sql: str, params: Optional[Tuple] = None) -> int:
|
1791
|
+
"""
|
1792
|
+
执行更新SQL语句(INSERT、UPDATE、DELETE)并返回影响的行数
|
1793
|
+
|
1794
|
+
:param sql: SQL更新语句
|
1795
|
+
:param params: SQL参数,可选
|
1796
|
+
:return: 影响的行数
|
1797
|
+
:raises: 可能抛出数据库相关异常
|
1798
|
+
"""
|
1799
|
+
if not sql or not isinstance(sql, str):
|
1800
|
+
logger.error('无效的SQL语句', {'sql': sql})
|
1801
|
+
raise ValueError('SQL语句不能为空且必须是字符串')
|
1802
|
+
|
1803
|
+
conn = None
|
1804
|
+
try:
|
1805
|
+
with self._get_connection() as conn:
|
1806
|
+
with conn.cursor() as cursor:
|
1807
|
+
affected_rows = cursor.execute(sql, params)
|
1808
|
+
conn.commit()
|
1809
|
+
logger.debug('更新执行成功', {
|
1810
|
+
'sql': self._shorten_for_log(sql, 100),
|
1811
|
+
'params': self._shorten_for_log(params, 50),
|
1812
|
+
'影响行数': affected_rows
|
1813
|
+
})
|
1814
|
+
return affected_rows
|
1815
|
+
except Exception as e:
|
1816
|
+
logger.error('执行更新时出错', {
|
1817
|
+
'sql': self._shorten_for_log(sql, 100),
|
1818
|
+
'params': self._shorten_for_log(params, 50),
|
1819
|
+
'error': str(e)
|
1820
|
+
})
|
1821
|
+
if conn is not None:
|
1822
|
+
conn.rollback()
|
1823
|
+
raise
|
1824
|
+
|
1756
1825
|
|
1757
1826
|
def main():
|
1758
1827
|
dir_path = os.path.expanduser("~")
|
mdbq/other/error_handler.py
CHANGED
@@ -79,13 +79,17 @@ def log_on_exception(
|
|
79
79
|
log_fields: Optional[List[str]] = None,
|
80
80
|
):
|
81
81
|
"""
|
82
|
-
:param logger:
|
82
|
+
:param logger: 日志对象,需实现 debug/info/warning/error/critical 方法
|
83
83
|
:param on_exception: 异常回调,参数为 error_info 字典
|
84
84
|
:param default_return: 异常时返回的默认值
|
85
85
|
:param log_fields: 只记录 error_info 的部分字段
|
86
86
|
"""
|
87
|
-
if logger is not None
|
88
|
-
|
87
|
+
if logger is not None:
|
88
|
+
for method in ("debug", "info", "warning", "error", "critical"):
|
89
|
+
if not hasattr(logger, method):
|
90
|
+
raise TypeError(
|
91
|
+
f"logger 参数必须有 {method} 方法,当前类型为: {type(logger)}"
|
92
|
+
)
|
89
93
|
def decorator(func):
|
90
94
|
is_async = asyncio.iscoroutinefunction(func)
|
91
95
|
@wraps(func)
|
@@ -142,13 +146,17 @@ def log_on_exception_with_retry(
|
|
142
146
|
log_fields: Optional[List[str]] = None,
|
143
147
|
):
|
144
148
|
"""
|
145
|
-
:param logger:
|
149
|
+
:param logger: 日志对象,需实现 debug/info/warning/error/critical 方法
|
146
150
|
:param on_exception: 异常回调,参数为 error_info 字典
|
147
151
|
:param default_return: 异常时返回的默认值
|
148
152
|
:param log_fields: 只记录 error_info 的部分字段
|
149
153
|
"""
|
150
|
-
if logger is not None
|
151
|
-
|
154
|
+
if logger is not None:
|
155
|
+
for method in ("debug", "info", "warning", "error", "critical"):
|
156
|
+
if not hasattr(logger, method):
|
157
|
+
raise TypeError(
|
158
|
+
f"logger 参数必须有 {method} 方法,当前类型为: {type(logger)}"
|
159
|
+
)
|
152
160
|
def decorator(func):
|
153
161
|
is_async = asyncio.iscoroutinefunction(func)
|
154
162
|
@wraps(func)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
2
|
-
mdbq/__version__.py,sha256=
|
2
|
+
mdbq/__version__.py,sha256=U1WMRZvqWGnnlhMX5A6NKB6YnAmRd4rS3atED7bLCQo,18
|
3
3
|
mdbq/aggregation/__init__.py,sha256=EeDqX2Aml6SPx8363J-v1lz0EcZtgwIBYyCJV6CcEDU,40
|
4
4
|
mdbq/aggregation/query_data.py,sha256=WtTFMN78jn43Y-nBTPAXhAK56w3wDuv_cj4YtzzGbZk,169797
|
5
5
|
mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
|
@@ -11,10 +11,10 @@ mdbq/mysql/deduplicator.py,sha256=AB3gL7ZwhcmzGHSu4UY4M6YZVPFZ2wlAN3BCcwAhegQ,73
|
|
11
11
|
mdbq/mysql/mysql.py,sha256=pDg771xBugCMSTWeskIFTi3pFLgaqgyG3smzf-86Wn8,56772
|
12
12
|
mdbq/mysql/s_query.py,sha256=1wJ3HVjHEF6FA-bVeeesRlsf73CZSvVTEQ51CF1OsE4,46786
|
13
13
|
mdbq/mysql/unique_.py,sha256=MaztT-WIyEQUs-OOYY4pFulgHVcXR1BfCy3QUz0XM_U,21127
|
14
|
-
mdbq/mysql/uploader.py,sha256=
|
14
|
+
mdbq/mysql/uploader.py,sha256=defQ4xCC3j8an9dWjFI3q_Fec0Irewe2FzBZqFL1GJM,84673
|
15
15
|
mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
16
16
|
mdbq/other/download_sku_picture.py,sha256=X66sVdvVgzoNzmgVJyPtd7bjEvctEKtLPblEPF65EWc,46940
|
17
|
-
mdbq/other/error_handler.py,sha256=
|
17
|
+
mdbq/other/error_handler.py,sha256=4p5haAXSY-P78stp4Xwo_MwAngWYqyKj5ogWIuYXMeY,12631
|
18
18
|
mdbq/other/otk.py,sha256=iclBIFbQbhlqzUbcMMoePXBpcP1eZ06ZtjnhcA_EbmE,7241
|
19
19
|
mdbq/other/pov_city.py,sha256=AEOmCOzOwyjHi9LLZWPKi6DUuSC-_M163664I52u9qw,21050
|
20
20
|
mdbq/other/ua_sj.py,sha256=JuVYzc_5QZ9s_oQSrTHVKkQv4S_7-CWx4oIKOARn_9U,22178
|
@@ -25,7 +25,7 @@ mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
|
25
25
|
mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
|
26
26
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
27
27
|
mdbq/spider/aikucun.py,sha256=XptHjGzbout9IYzWAOQUpMMV5qEgLTU8pL1ZGt8oNEA,21868
|
28
|
-
mdbq-4.0.
|
29
|
-
mdbq-4.0.
|
30
|
-
mdbq-4.0.
|
31
|
-
mdbq-4.0.
|
28
|
+
mdbq-4.0.38.dist-info/METADATA,sha256=edMyLlQlfms58lylwf4zSHXWbqA8C9jFwJ-YHT-p_cs,364
|
29
|
+
mdbq-4.0.38.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
30
|
+
mdbq-4.0.38.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
31
|
+
mdbq-4.0.38.dist-info/RECORD,,
|
File without changes
|
File without changes
|