lazy-mysql 0.1.0__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.
- lazy_mysql-0.1.0/LICENSE +21 -0
- lazy_mysql-0.1.0/PKG-INFO +66 -0
- lazy_mysql-0.1.0/README.md +51 -0
- lazy_mysql-0.1.0/lazy_mysql.egg-info/PKG-INFO +66 -0
- lazy_mysql-0.1.0/lazy_mysql.egg-info/SOURCES.txt +17 -0
- lazy_mysql-0.1.0/lazy_mysql.egg-info/dependency_links.txt +1 -0
- lazy_mysql-0.1.0/lazy_mysql.egg-info/requires.txt +1 -0
- lazy_mysql-0.1.0/lazy_mysql.egg-info/top_level.txt +2 -0
- lazy_mysql-0.1.0/setup.cfg +4 -0
- lazy_mysql-0.1.0/setup.py +22 -0
- lazy_mysql-0.1.0/tools/__init__.py +0 -0
- lazy_mysql-0.1.0/tools/result_formatter.py +43 -0
- lazy_mysql-0.1.0/tools/table_export.py +36 -0
- lazy_mysql-0.1.0/tools/where_clause.py +26 -0
- lazy_mysql-0.1.0/utils/__init__.py +0 -0
- lazy_mysql-0.1.0/utils/connect.py +58 -0
- lazy_mysql-0.1.0/utils/insert.py +18 -0
- lazy_mysql-0.1.0/utils/select.py +104 -0
- lazy_mysql-0.1.0/utils/update.py +26 -0
lazy_mysql-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 tinycen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: lazy_mysql
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lazy MySQL client for Python
|
|
5
|
+
Home-page: https://github.com/tinycen/lazy_mysql
|
|
6
|
+
Author: tinycen
|
|
7
|
+
Author-email: sky_ruocen@qq.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: pymysql
|
|
15
|
+
|
|
16
|
+
# lazy_mysql
|
|
17
|
+
|
|
18
|
+
A lightweight Python library for simplified MySQL database operations.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Unified SQL execution interface
|
|
23
|
+
- Export table structure to Markdown format
|
|
24
|
+
- Query result formatting
|
|
25
|
+
- Simplified insert, update, and select operations
|
|
26
|
+
- Transaction support
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install -e .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from lazy_mysql.executor import SQLExecutor
|
|
38
|
+
|
|
39
|
+
# Initialize connection
|
|
40
|
+
config = {
|
|
41
|
+
'host': 'localhost',
|
|
42
|
+
'user': 'root',
|
|
43
|
+
'password': 'password',
|
|
44
|
+
'database': 'test_db'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
executor = SQLExecutor(config)
|
|
48
|
+
|
|
49
|
+
# Query example
|
|
50
|
+
result = executor.select('users', ['id', 'name'])
|
|
51
|
+
print(result)
|
|
52
|
+
|
|
53
|
+
# Insert example
|
|
54
|
+
executor.insert('users', {'name': 'John', 'age': 30}, commit=True)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
- mysql-connector-python>=9.4.0
|
|
60
|
+
- pandas>=2.3.1
|
|
61
|
+
|
|
62
|
+
Note: Compatibility with versions below these requirements has not been verified.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# lazy_mysql
|
|
2
|
+
|
|
3
|
+
A lightweight Python library for simplified MySQL database operations.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Unified SQL execution interface
|
|
8
|
+
- Export table structure to Markdown format
|
|
9
|
+
- Query result formatting
|
|
10
|
+
- Simplified insert, update, and select operations
|
|
11
|
+
- Transaction support
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from lazy_mysql.executor import SQLExecutor
|
|
23
|
+
|
|
24
|
+
# Initialize connection
|
|
25
|
+
config = {
|
|
26
|
+
'host': 'localhost',
|
|
27
|
+
'user': 'root',
|
|
28
|
+
'password': 'password',
|
|
29
|
+
'database': 'test_db'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
executor = SQLExecutor(config)
|
|
33
|
+
|
|
34
|
+
# Query example
|
|
35
|
+
result = executor.select('users', ['id', 'name'])
|
|
36
|
+
print(result)
|
|
37
|
+
|
|
38
|
+
# Insert example
|
|
39
|
+
executor.insert('users', {'name': 'John', 'age': 30}, commit=True)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Requirements
|
|
43
|
+
|
|
44
|
+
- mysql-connector-python>=9.4.0
|
|
45
|
+
- pandas>=2.3.1
|
|
46
|
+
|
|
47
|
+
Note: Compatibility with versions below these requirements has not been verified.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## License
|
|
51
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: lazy-mysql
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lazy MySQL client for Python
|
|
5
|
+
Home-page: https://github.com/tinycen/lazy_mysql
|
|
6
|
+
Author: tinycen
|
|
7
|
+
Author-email: sky_ruocen@qq.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: pymysql
|
|
15
|
+
|
|
16
|
+
# lazy_mysql
|
|
17
|
+
|
|
18
|
+
A lightweight Python library for simplified MySQL database operations.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Unified SQL execution interface
|
|
23
|
+
- Export table structure to Markdown format
|
|
24
|
+
- Query result formatting
|
|
25
|
+
- Simplified insert, update, and select operations
|
|
26
|
+
- Transaction support
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install -e .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from lazy_mysql.executor import SQLExecutor
|
|
38
|
+
|
|
39
|
+
# Initialize connection
|
|
40
|
+
config = {
|
|
41
|
+
'host': 'localhost',
|
|
42
|
+
'user': 'root',
|
|
43
|
+
'password': 'password',
|
|
44
|
+
'database': 'test_db'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
executor = SQLExecutor(config)
|
|
48
|
+
|
|
49
|
+
# Query example
|
|
50
|
+
result = executor.select('users', ['id', 'name'])
|
|
51
|
+
print(result)
|
|
52
|
+
|
|
53
|
+
# Insert example
|
|
54
|
+
executor.insert('users', {'name': 'John', 'age': 30}, commit=True)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
- mysql-connector-python>=9.4.0
|
|
60
|
+
- pandas>=2.3.1
|
|
61
|
+
|
|
62
|
+
Note: Compatibility with versions below these requirements has not been verified.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
lazy_mysql.egg-info/PKG-INFO
|
|
5
|
+
lazy_mysql.egg-info/SOURCES.txt
|
|
6
|
+
lazy_mysql.egg-info/dependency_links.txt
|
|
7
|
+
lazy_mysql.egg-info/requires.txt
|
|
8
|
+
lazy_mysql.egg-info/top_level.txt
|
|
9
|
+
tools/__init__.py
|
|
10
|
+
tools/result_formatter.py
|
|
11
|
+
tools/table_export.py
|
|
12
|
+
tools/where_clause.py
|
|
13
|
+
utils/__init__.py
|
|
14
|
+
utils/connect.py
|
|
15
|
+
utils/insert.py
|
|
16
|
+
utils/select.py
|
|
17
|
+
utils/update.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pymysql
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='lazy_mysql',
|
|
5
|
+
version='0.1.0',
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
install_requires=[
|
|
8
|
+
'pymysql',
|
|
9
|
+
],
|
|
10
|
+
author='tinycen',
|
|
11
|
+
author_email='sky_ruocen@qq.com',
|
|
12
|
+
description='A lazy MySQL client for Python',
|
|
13
|
+
long_description=open('README.md').read(),
|
|
14
|
+
long_description_content_type='text/markdown',
|
|
15
|
+
url='https://github.com/tinycen/lazy_mysql',
|
|
16
|
+
classifiers=[
|
|
17
|
+
'Programming Language :: Python :: 3',
|
|
18
|
+
'License :: OSI Approved :: MIT License',
|
|
19
|
+
'Operating System :: OS Independent',
|
|
20
|
+
],
|
|
21
|
+
python_requires='>=3.10',
|
|
22
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
def fetch_format( executor , sql , fetch_mode , output_format = "" , show_count = False , data_label = None ,
|
|
4
|
+
params = None , self_close = False ) :
|
|
5
|
+
"""
|
|
6
|
+
定义解析结果程序(格式化返回结果)
|
|
7
|
+
:param executor: SQLExecutor 实例
|
|
8
|
+
:param sql: SQL语句
|
|
9
|
+
:param fetch_mode: 获取模式
|
|
10
|
+
:param output_format: 输出格式
|
|
11
|
+
:param show_count: 是否显示结果数量
|
|
12
|
+
:param data_label: 数据标签
|
|
13
|
+
:param params: 参数
|
|
14
|
+
:param self_close: 是否自动关闭连接
|
|
15
|
+
:return: 查询结果
|
|
16
|
+
"""
|
|
17
|
+
executor.execute( sql , params , self_close = self_close )
|
|
18
|
+
|
|
19
|
+
if data_label is None :
|
|
20
|
+
data_label = [ ]
|
|
21
|
+
|
|
22
|
+
if fetch_mode == "all" :
|
|
23
|
+
myresult = executor.mycursor.fetchall() # 接收全部的返回结果行,返回结果为 tuple(元组)
|
|
24
|
+
if output_format == "list_1" :
|
|
25
|
+
if myresult is None :
|
|
26
|
+
return [ ]
|
|
27
|
+
data = [ myresult[ 0 ] for myresult in myresult ] if myresult else [ ]
|
|
28
|
+
myresult = data
|
|
29
|
+
elif "df" in output_format :
|
|
30
|
+
myresult = pd.DataFrame( myresult , columns = data_label )
|
|
31
|
+
if "dict" in output_format :
|
|
32
|
+
myresult = myresult.to_dict( "records" )
|
|
33
|
+
elif fetch_mode == "oneTuple" :
|
|
34
|
+
myresult = executor.mycursor.fetchone() # 接收全部的返回结果行,返回结果为 tuple(元组)
|
|
35
|
+
else :
|
|
36
|
+
result = executor.mycursor.fetchone()
|
|
37
|
+
myresult = result[ 0 ] if result else None
|
|
38
|
+
|
|
39
|
+
if show_count :
|
|
40
|
+
num = len( myresult )
|
|
41
|
+
print( f"查询结果数量:{num}" )
|
|
42
|
+
return myresult , num
|
|
43
|
+
return myresult
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
def export_table_md( executor , table_name , save_path = None , self_close = True ) :
|
|
2
|
+
"""
|
|
3
|
+
将 table 中的字段和字段类型,导出为md格式文件
|
|
4
|
+
:param executor: SQLExecutor 实例
|
|
5
|
+
:param table_name: 表名
|
|
6
|
+
:param save_path: 保存路径
|
|
7
|
+
:param self_close: 是否自动关闭连接
|
|
8
|
+
:return: None
|
|
9
|
+
"""
|
|
10
|
+
# 检查表是否存在
|
|
11
|
+
executor.execute(f"SHOW TABLES LIKE '{table_name}'", self_close=False)
|
|
12
|
+
if not executor.mycursor.fetchone():
|
|
13
|
+
raise ValueError(f"表 {table_name} 不存在")
|
|
14
|
+
|
|
15
|
+
# 执行查询获取表结构(使用SHOW FULL COLUMNS)
|
|
16
|
+
query = f"SHOW FULL COLUMNS FROM {table_name}"
|
|
17
|
+
print(f"执行查询: {query}") # 调试输出
|
|
18
|
+
executor.execute(query , self_close = self_close)
|
|
19
|
+
# 获取查询结果
|
|
20
|
+
result = executor.mycursor.fetchall()
|
|
21
|
+
# print(f"原始查询结果: {result}") # 调试输出
|
|
22
|
+
|
|
23
|
+
# 解析结果(取Field,Type,Comment字段)
|
|
24
|
+
result = [(row[0], row[1], row[8]) for row in result]
|
|
25
|
+
# 解析结果并生成Markdown内容
|
|
26
|
+
md_content = f"## {table_name} 表结构\n\n"
|
|
27
|
+
md_content += "| 字段名 | 字段类型 | 字段描述 |\n"
|
|
28
|
+
md_content += "| --- | --- | --- |\n"
|
|
29
|
+
for row in result:
|
|
30
|
+
field_name, field_type, field_comment = row
|
|
31
|
+
md_content += f"| {field_name} | {field_type} | {field_comment} |\n"
|
|
32
|
+
# 写入Markdown文件
|
|
33
|
+
if save_path is None :
|
|
34
|
+
save_path = f"{table_name}.md"
|
|
35
|
+
with open(save_path, 'w', encoding='utf-8') as md_file:
|
|
36
|
+
md_file.write(md_content)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
def build_where_clause( where_conditions ) :
|
|
2
|
+
"""
|
|
3
|
+
构造WHERE子句和对应的参数列表
|
|
4
|
+
|
|
5
|
+
:param where_conditions: WHERE条件,格式为字典,每个值可以是:
|
|
6
|
+
- 简单值: 默认使用 = 比较
|
|
7
|
+
- 元组: (比较运算符, 值) 如 ('>', 100)
|
|
8
|
+
:return: (where_clause, params) - WHERE子句字符串和参数列表
|
|
9
|
+
"""
|
|
10
|
+
if not where_conditions :
|
|
11
|
+
return None , None
|
|
12
|
+
|
|
13
|
+
clauses = []
|
|
14
|
+
params = []
|
|
15
|
+
|
|
16
|
+
for field, value in where_conditions.items() :
|
|
17
|
+
if isinstance(value, tuple) and len(value) == 2 :
|
|
18
|
+
operator, val = value
|
|
19
|
+
clauses.append(f"{field} {operator} %s")
|
|
20
|
+
params.append(val)
|
|
21
|
+
else :
|
|
22
|
+
clauses.append(f"{field} = %s")
|
|
23
|
+
params.append(value)
|
|
24
|
+
|
|
25
|
+
where_clause = ' AND '.join(clauses)
|
|
26
|
+
return where_clause , params
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import mysql.connector
|
|
2
|
+
|
|
3
|
+
# 获取数据库连接和游标
|
|
4
|
+
def connection( sql_config ,database=None ) :
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
建立数据库连接并返回连接对象和游标对象
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
sql_config (object): 数据库配置对象,包含host, port, user, passwd, default_database等属性
|
|
11
|
+
database (str, optional): 数据库名称,database参数优先使用,默认使用 sql_config.default_database
|
|
12
|
+
Returns:
|
|
13
|
+
tuple: (数据库连接对象, 游标对象)
|
|
14
|
+
"""
|
|
15
|
+
if database is not None :
|
|
16
|
+
database = database
|
|
17
|
+
elif not hasattr(sql_config, 'default_database') or sql_config.default_database is None:
|
|
18
|
+
database = "new_schema"
|
|
19
|
+
else:
|
|
20
|
+
database = sql_config.default_database
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
# 新版本使用password参数和推荐参数
|
|
24
|
+
# buffered=True - 缓冲查询结果,避免多次查询时出现'Unread result found'错误
|
|
25
|
+
# pool_size=5 - 连接池最大连接数,控制并发连接数量,
|
|
26
|
+
# pool_reset_session=True - 连接返回池时重置会话变量,确保连接状态干净
|
|
27
|
+
# pool_name="shop_pool" - 连接池名称,用于标识和管理连接池
|
|
28
|
+
# 如果设置了 pool_reset_session 就必须设置 pool_name ,省略会报错- AttributeError:
|
|
29
|
+
# Pool name 'rm-wz93y5aqe2f5gvu5uto.mysql.rds.aliyuncs.com_3306_root_yqq_new_schema' is too long
|
|
30
|
+
# use_pure=True - 使用纯Python实现而非C扩展,提高兼容性,减少外部依赖(实测,设置在为False会导致连接失败!)
|
|
31
|
+
|
|
32
|
+
mydb = mysql.connector.connect(
|
|
33
|
+
host=sql_config.host,
|
|
34
|
+
port=sql_config.port,
|
|
35
|
+
user=sql_config.user,
|
|
36
|
+
password=sql_config.passwd,
|
|
37
|
+
database=database,
|
|
38
|
+
buffered=True,
|
|
39
|
+
use_pure=True
|
|
40
|
+
)
|
|
41
|
+
mycursor = mydb.cursor(buffered=True)
|
|
42
|
+
except TypeError:
|
|
43
|
+
# 旧版本兼容模式
|
|
44
|
+
mydb = mysql.connector.connect(
|
|
45
|
+
host=sql_config.host,
|
|
46
|
+
port=sql_config.port,
|
|
47
|
+
user=sql_config.user,
|
|
48
|
+
passwd=sql_config.passwd,
|
|
49
|
+
database=database,
|
|
50
|
+
use_pure=True
|
|
51
|
+
)
|
|
52
|
+
mycursor = mydb.cursor()
|
|
53
|
+
|
|
54
|
+
# 检查版本是否过时
|
|
55
|
+
if tuple(map(int, mysql.connector.__version__.split('.')[:2])) < (9, 4):
|
|
56
|
+
print(f"警告: MySQL连接器版本{mysql.connector.__version__}已过时,建议升级到9.4.0或更高版本")
|
|
57
|
+
print("pip install --upgrade mysql-connector-python")
|
|
58
|
+
return mydb , mycursor
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from ..executor import SQLExecutor
|
|
2
|
+
|
|
3
|
+
def insert(executor: SQLExecutor, table_name, insert_fields, commit=False, self_close=False):
|
|
4
|
+
"""
|
|
5
|
+
通用的SQL插入执行器方法,
|
|
6
|
+
:param executor: SQLExecutor 实例
|
|
7
|
+
:param table_name: 表名
|
|
8
|
+
:param insert_fields: 字段和值,格式为字典,如 {'field1': 'value1', 'field2': 'value2'}
|
|
9
|
+
:param commit: 是否自动提交
|
|
10
|
+
:param self_close: 是否自动关闭连接
|
|
11
|
+
:return: None
|
|
12
|
+
"""
|
|
13
|
+
# 构造SQL语句
|
|
14
|
+
sql = f'''INSERT INTO {table_name}
|
|
15
|
+
({', '.join(insert_fields.keys())}) VALUES ({', '.join(['%s'] * len(insert_fields))});'''
|
|
16
|
+
values = tuple(insert_fields.values())
|
|
17
|
+
|
|
18
|
+
executor.execute(sql, values, commit, self_close)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from ..executor import SQLExecutor
|
|
2
|
+
from ..tools.where_clause import build_where_clause
|
|
3
|
+
|
|
4
|
+
def select(executor: SQLExecutor, table_names, select_fields, where_conditions, order_by=None, limit=None,
|
|
5
|
+
join_conditions=None, self_close=False, fetch_config=None):
|
|
6
|
+
"""
|
|
7
|
+
通用的SQL查询执行器方法,支持JOIN操作
|
|
8
|
+
:param executor: SQLExecutor 实例
|
|
9
|
+
:param table_names: 表名,可以是字符串或列表
|
|
10
|
+
:param select_fields: 要查询的字段列表
|
|
11
|
+
:param where_conditions: WHERE条件,格式为字典
|
|
12
|
+
:param order_by: ORDER BY子句
|
|
13
|
+
:param limit: LIMIT子句
|
|
14
|
+
:param join_conditions: JOIN条件,格式为字典,如 {"join_type": "JOIN", "conditions": ["field1", "=", "field2"]}
|
|
15
|
+
:param self_close: 是否自动关闭连接
|
|
16
|
+
:param fetch_config: 获取配置
|
|
17
|
+
:return: 查询结果
|
|
18
|
+
"""
|
|
19
|
+
# 处理select_fields参数
|
|
20
|
+
if isinstance(select_fields, dict):
|
|
21
|
+
# 如果是字典,自动添加表名前缀
|
|
22
|
+
processed_fields = []
|
|
23
|
+
for table, fields in select_fields.items():
|
|
24
|
+
for field in fields:
|
|
25
|
+
processed_fields.append(f"{table}.{field}")
|
|
26
|
+
columns = processed_fields
|
|
27
|
+
else :
|
|
28
|
+
columns = select_fields
|
|
29
|
+
# 构造select子句
|
|
30
|
+
select_clause = ', '.join(columns)
|
|
31
|
+
|
|
32
|
+
# 处理表名
|
|
33
|
+
if isinstance(table_names, str):
|
|
34
|
+
# 单个表
|
|
35
|
+
sql = f"SELECT {select_clause} FROM {table_names}"
|
|
36
|
+
elif isinstance(table_names, list):
|
|
37
|
+
# 多个表,需要JOIN
|
|
38
|
+
main_table = table_names[0]
|
|
39
|
+
sql = f"SELECT {select_clause} FROM {main_table}"
|
|
40
|
+
|
|
41
|
+
# 添加JOIN子句
|
|
42
|
+
if join_conditions:
|
|
43
|
+
# JOIN操作,table_names必须是包含至少两个表名的列表
|
|
44
|
+
if isinstance(table_names, str) or len(table_names) < 2:
|
|
45
|
+
raise ValueError("存在JOIN操作时,table_names必须是包含至少两个表名的列表")
|
|
46
|
+
join_type = join_conditions.get("join_type", "JOIN")
|
|
47
|
+
conditions = join_conditions.get("conditions", [])
|
|
48
|
+
|
|
49
|
+
# 为每个额外的表添加JOIN子句
|
|
50
|
+
for i, join_table in enumerate(table_names[1:], start=1):
|
|
51
|
+
# 如果提供了具体的JOIN条件,则使用它
|
|
52
|
+
if conditions and len(conditions) >= 3:
|
|
53
|
+
field1, operator, field2 = conditions[0], conditions[1], conditions[2]
|
|
54
|
+
# 如果字段名没有表前缀,添加主表前缀
|
|
55
|
+
if '.' not in field1:
|
|
56
|
+
field1 = f"{main_table}.{field1}"
|
|
57
|
+
if '.' not in field2:
|
|
58
|
+
field2 = f"{join_table}.{field2}"
|
|
59
|
+
sql += f" {join_type} {join_table} ON {field1} {operator} {field2}"
|
|
60
|
+
else:
|
|
61
|
+
# 默认使用item_id进行JOIN
|
|
62
|
+
sql += f" {join_type} {join_table} ON {main_table}.item_id = {join_table}.item_id"
|
|
63
|
+
else:
|
|
64
|
+
raise ValueError("table_names must be a string or a list of strings")
|
|
65
|
+
|
|
66
|
+
# 构造WHERE子句
|
|
67
|
+
where_clause, params = build_where_clause(where_conditions)
|
|
68
|
+
if where_clause:
|
|
69
|
+
sql += f" WHERE {where_clause}"
|
|
70
|
+
|
|
71
|
+
# 添加ORDER BY子句(如果提供)
|
|
72
|
+
if order_by:
|
|
73
|
+
sql += f" ORDER BY {order_by}"
|
|
74
|
+
|
|
75
|
+
# 添加LIMIT子句(如果提供)
|
|
76
|
+
if limit:
|
|
77
|
+
sql += f" LIMIT {limit}"
|
|
78
|
+
|
|
79
|
+
if fetch_config is None:
|
|
80
|
+
fetch_config = {}
|
|
81
|
+
|
|
82
|
+
fetch_mode = fetch_config["fetch_mode"]
|
|
83
|
+
output_format = fetch_config["output_format"]
|
|
84
|
+
show_count = fetch_config.get("show_count", False)
|
|
85
|
+
|
|
86
|
+
# 获取data_label参数
|
|
87
|
+
data_label = fetch_config.get("data_label", None)
|
|
88
|
+
|
|
89
|
+
# 如果data_label为None,则根据select_fields自动生成
|
|
90
|
+
if data_label is None and "df" in output_format :
|
|
91
|
+
if isinstance(select_fields, dict):
|
|
92
|
+
# 如果select_fields是字典,展平为列表
|
|
93
|
+
data_label = []
|
|
94
|
+
for table, fields in select_fields.items():
|
|
95
|
+
for field in fields:
|
|
96
|
+
if field in data_label :
|
|
97
|
+
raise ValueError(f"字段值重复:Field '{field}' already exists in data_label")
|
|
98
|
+
data_label.append(field)
|
|
99
|
+
else:
|
|
100
|
+
# 如果select_fields是列表,直接使用
|
|
101
|
+
data_label = select_fields
|
|
102
|
+
|
|
103
|
+
result = executor.fetch_format(sql, fetch_mode, output_format, show_count, data_label, params, self_close)
|
|
104
|
+
return result
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from ..executor import SQLExecutor
|
|
2
|
+
from ..tools.where_clause import build_where_clause
|
|
3
|
+
|
|
4
|
+
def update(executor: SQLExecutor, table_name, update_fields, where_conditions, commit=False, self_close=False):
|
|
5
|
+
"""
|
|
6
|
+
通用的SQL更新执行器方法,支持动态构造WHERE子句
|
|
7
|
+
|
|
8
|
+
:param executor: SQLExecutor 实例
|
|
9
|
+
:param table_name: 表名
|
|
10
|
+
:param update_fields: 需要更新的字段和值,格式为字典,如 {'field1': 'value1', 'field2': 'value2'}
|
|
11
|
+
:param where_conditions: WHERE条件,格式为字典,如 {'field1': 'value1', 'field2': 'value2'}
|
|
12
|
+
:param commit: 是否自动提交
|
|
13
|
+
:param self_close: 是否自动关闭连接
|
|
14
|
+
:return: None
|
|
15
|
+
"""
|
|
16
|
+
# 构造SET子句
|
|
17
|
+
set_clause = ', '.join([f"{field} = %s" for field in update_fields.keys()])
|
|
18
|
+
|
|
19
|
+
# 构造WHERE子句
|
|
20
|
+
where_clause, params = build_where_clause(where_conditions)
|
|
21
|
+
|
|
22
|
+
# 构造SQL语句
|
|
23
|
+
sql = f'''UPDATE {table_name} SET {set_clause} WHERE {where_clause};'''
|
|
24
|
+
|
|
25
|
+
# 执行SQL
|
|
26
|
+
executor.execute(sql, params, commit, self_close)
|