db_client_toolkit 0.0.1__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.
- db_client_toolkit-0.0.1.dist-info/METADATA +540 -0
- db_client_toolkit-0.0.1.dist-info/RECORD +22 -0
- db_client_toolkit-0.0.1.dist-info/WHEEL +4 -0
- db_toolkit/__init__.py +151 -0
- db_toolkit/clients/__init__.py +20 -0
- db_toolkit/clients/mongodb.py +251 -0
- db_toolkit/clients/mysql.py +143 -0
- db_toolkit/clients/postgresql.py +152 -0
- db_toolkit/clients/redis.py +321 -0
- db_toolkit/clients/sqlite.py +152 -0
- db_toolkit/clients/supabase.py +230 -0
- db_toolkit/core/__init__.py +9 -0
- db_toolkit/core/base.py +194 -0
- db_toolkit/core/sql_base.py +163 -0
- db_toolkit/exceptions/__init__.py +38 -0
- db_toolkit/mixins/__init__.py +12 -0
- db_toolkit/mixins/batch_ops.py +194 -0
- db_toolkit/mixins/transaction.py +206 -0
- db_toolkit/utils/__init__.py +15 -0
- db_toolkit/utils/config.py +252 -0
- db_toolkit/utils/factory.py +172 -0
- db_toolkit/utils/query_builder.py +316 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: db_client_toolkit
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: 统一的跨平台数据库工具库
|
|
5
|
+
Author: hanpj
|
|
6
|
+
Author-email: hanpj7524@gmail.com
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Requires-Dist: mysql-connector-python (>=8.0.0)
|
|
16
|
+
Requires-Dist: psycopg2-binary (>=2.9.0)
|
|
17
|
+
Requires-Dist: pymongo (>=4.0.0)
|
|
18
|
+
Requires-Dist: redis (>=4.0.0)
|
|
19
|
+
Requires-Dist: supabase (>=2.0.0)
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Database Toolkit
|
|
23
|
+
|
|
24
|
+
一个强大、易用、可扩展的Python数据库客户端工具包,支持多种数据库类型,提供统一的API接口。
|
|
25
|
+
|
|
26
|
+
[](https://www.python.org/downloads/)
|
|
27
|
+
[](LICENSE)
|
|
28
|
+
|
|
29
|
+
## ✨ 特性
|
|
30
|
+
|
|
31
|
+
- 🔌 **多数据库支持**: MySQL、PostgreSQL、SQLite、MongoDB、Redis、Supabase
|
|
32
|
+
- 🎯 **统一API**: 所有数据库使用相同的接口方法
|
|
33
|
+
- 🏗️ **模块化设计**: 清晰的代码结构,易于维护和扩展
|
|
34
|
+
- 🔒 **自动连接管理**: 支持上下文管理器
|
|
35
|
+
- 🏭 **工厂模式**: 便捷的客户端创建
|
|
36
|
+
- 📦 **批量操作**: 内置批量插入、更新、删除功能
|
|
37
|
+
- 💾 **事务支持**: 完整的事务管理
|
|
38
|
+
- 🔧 **查询构建器**: 流畅的SQL构建API
|
|
39
|
+
- ⚙️ **配置管理**: JSON配置文件支持
|
|
40
|
+
- 🔌 **可扩展**: 支持自定义数据库客户端
|
|
41
|
+
- 🛡️ **类型安全**: 完整的类型注解
|
|
42
|
+
- 📝 **异常处理**: 详细的异常类型和错误信息
|
|
43
|
+
|
|
44
|
+
## 📦 安装
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 克隆仓库
|
|
48
|
+
git clone https://github.com/your/db-toolkit.git
|
|
49
|
+
cd db-toolkit
|
|
50
|
+
|
|
51
|
+
# 安装依赖(根据需要选择)
|
|
52
|
+
# MySQL
|
|
53
|
+
pip install mysql-connector-python
|
|
54
|
+
|
|
55
|
+
# PostgreSQL
|
|
56
|
+
pip install psycopg2-binary
|
|
57
|
+
|
|
58
|
+
# MongoDB
|
|
59
|
+
pip install pymongo
|
|
60
|
+
|
|
61
|
+
# Redis
|
|
62
|
+
pip install redis
|
|
63
|
+
|
|
64
|
+
# Supabase
|
|
65
|
+
pip install supabase
|
|
66
|
+
|
|
67
|
+
# SQLite (Python内置,无需安装)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 🚀 快速开始
|
|
71
|
+
|
|
72
|
+
### 基础用法
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from db_toolkit import create_client
|
|
76
|
+
|
|
77
|
+
# 连接SQLite数据库
|
|
78
|
+
config = {'database': 'myapp.db'}
|
|
79
|
+
|
|
80
|
+
with create_client('sqlite', config) as client:
|
|
81
|
+
# 插入数据
|
|
82
|
+
user_id = client.insert('users', {
|
|
83
|
+
'name': 'Alice',
|
|
84
|
+
'email': 'alice@example.com',
|
|
85
|
+
'age': 25
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
# 查询数据
|
|
89
|
+
users = client.select('users', condition={'age': 25})
|
|
90
|
+
|
|
91
|
+
# 更新数据
|
|
92
|
+
client.update('users', {'age': 26}, {'id': user_id})
|
|
93
|
+
|
|
94
|
+
# 删除数据
|
|
95
|
+
client.delete('users', {'id': user_id})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 📚 详细文档
|
|
99
|
+
|
|
100
|
+
### 项目结构
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
db_toolkit/
|
|
104
|
+
├── __init__.py # 包初始化,导出公共API
|
|
105
|
+
├── core/ # 核心模块
|
|
106
|
+
│ ├── __init__.py
|
|
107
|
+
│ ├── base.py # 抽象基类
|
|
108
|
+
│ └── sql_base.py # SQL数据库基类
|
|
109
|
+
├── clients/ # 数据库客户端实现
|
|
110
|
+
│ ├── __init__.py
|
|
111
|
+
│ ├── mysql.py # MySQL客户端
|
|
112
|
+
│ ├── postgresql.py # PostgreSQL客户端
|
|
113
|
+
│ ├── sqlite.py # SQLite客户端
|
|
114
|
+
│ ├── mongodb.py # MongoDB客户端
|
|
115
|
+
│ ├── redis.py # Redis客户端
|
|
116
|
+
│ └── supabase.py # Supabase客户端
|
|
117
|
+
├── utils/ # 工具类
|
|
118
|
+
│ ├── __init__.py
|
|
119
|
+
│ ├── factory.py # 客户端工厂
|
|
120
|
+
│ ├── config.py # 配置管理器
|
|
121
|
+
│ └── query_builder.py # 查询构建器
|
|
122
|
+
├── mixins/ # 混入类
|
|
123
|
+
│ ├── __init__.py
|
|
124
|
+
│ ├── batch_ops.py # 批量操作
|
|
125
|
+
│ └── transaction.py # 事务管理
|
|
126
|
+
└── exceptions/ # 自定义异常
|
|
127
|
+
└── __init__.py
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 支持的数据库
|
|
131
|
+
|
|
132
|
+
#### 1. MySQL
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
config = {
|
|
136
|
+
'host': 'localhost',
|
|
137
|
+
'port': 3306,
|
|
138
|
+
'user': 'root',
|
|
139
|
+
'password': 'password',
|
|
140
|
+
'database': 'mydb'
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
with create_client('mysql', config) as client:
|
|
144
|
+
users = client.select('users', limit=10)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### 2. PostgreSQL
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
config = {
|
|
151
|
+
'host': 'localhost',
|
|
152
|
+
'port': 5432,
|
|
153
|
+
'user': 'postgres',
|
|
154
|
+
'password': 'password',
|
|
155
|
+
'database': 'mydb'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
with create_client('postgresql', config) as client:
|
|
159
|
+
count = client.count('users')
|
|
160
|
+
exists = client.exists('users', {'email': 'user@example.com'})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### 3. SQLite
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
config = {
|
|
167
|
+
'database': 'myapp.db' # 或 ':memory:' 用于内存数据库
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
with create_client('sqlite', config) as client:
|
|
171
|
+
# SQLite特有功能
|
|
172
|
+
client.execute_script('''
|
|
173
|
+
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);
|
|
174
|
+
INSERT INTO users VALUES (1, 'Alice');
|
|
175
|
+
''')
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### 4. MongoDB
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
# 方式1: 连接字符串
|
|
182
|
+
config = {
|
|
183
|
+
'connection_string': 'mongodb://localhost:27017/',
|
|
184
|
+
'database': 'mydb'
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# 方式2: 主机/端口
|
|
188
|
+
config = {
|
|
189
|
+
'host': 'localhost',
|
|
190
|
+
'port': 27017,
|
|
191
|
+
'database': 'mydb'
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
with create_client('mongodb', config) as client:
|
|
195
|
+
# MongoDB特有功能
|
|
196
|
+
doc_ids = client.insert_many('users', [
|
|
197
|
+
{'name': 'Alice', 'age': 25},
|
|
198
|
+
{'name': 'Bob', 'age': 30}
|
|
199
|
+
])
|
|
200
|
+
|
|
201
|
+
# 聚合查询
|
|
202
|
+
results = client.aggregate('orders', [
|
|
203
|
+
{'$match': {'status': 'completed'}},
|
|
204
|
+
{'$group': {'_id': '$user_id', 'total': {'$sum': '$amount'}}}
|
|
205
|
+
])
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### 5. Redis
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
config = {
|
|
212
|
+
'host': 'localhost',
|
|
213
|
+
'port': 6379,
|
|
214
|
+
'db': 0,
|
|
215
|
+
'password': None
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
with create_client('redis', config) as client:
|
|
219
|
+
# 字符串操作
|
|
220
|
+
client.set('key', 'value', ex=3600)
|
|
221
|
+
value = client.get('key')
|
|
222
|
+
|
|
223
|
+
# Hash操作
|
|
224
|
+
client.hset('user:1', mapping={'name': 'Alice', 'age': '25'})
|
|
225
|
+
user = client.hgetall('user:1')
|
|
226
|
+
|
|
227
|
+
# 通用接口
|
|
228
|
+
client.insert('users', {'id': '1', 'name': 'Alice'})
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### 6. Supabase
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
config = {
|
|
235
|
+
'url': 'https://your-project.supabase.co',
|
|
236
|
+
'key': 'your-anon-key'
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
with create_client('supabase', config) as client:
|
|
240
|
+
# Supabase特有功能
|
|
241
|
+
data = client.upsert('users', {
|
|
242
|
+
'id': 1,
|
|
243
|
+
'name': 'Alice',
|
|
244
|
+
'email': 'alice@example.com'
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
# 调用RPC函数
|
|
248
|
+
result = client.rpc('get_user_stats', {'user_id': 1})
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 高级功能
|
|
252
|
+
|
|
253
|
+
#### 配置管理
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
from db_toolkit import ConfigManager
|
|
257
|
+
|
|
258
|
+
# 创建配置管理器
|
|
259
|
+
manager = ConfigManager('db_config.json')
|
|
260
|
+
|
|
261
|
+
# 添加配置
|
|
262
|
+
manager.add('production', 'postgresql', {
|
|
263
|
+
'host': 'prod-server.com',
|
|
264
|
+
'user': 'app',
|
|
265
|
+
'password': 'secret',
|
|
266
|
+
'database': 'prod_db'
|
|
267
|
+
}, set_as_default=True)
|
|
268
|
+
|
|
269
|
+
manager.add('development', 'sqlite', {
|
|
270
|
+
'database': 'dev.db'
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
# 使用配置
|
|
274
|
+
with manager.get_client('production') as client:
|
|
275
|
+
# 使用生产数据库
|
|
276
|
+
users = client.select('users')
|
|
277
|
+
|
|
278
|
+
# 使用默认配置
|
|
279
|
+
with manager.get_client() as client:
|
|
280
|
+
# 自动使用production(设置为默认)
|
|
281
|
+
pass
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### 查询构建器
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
from db_toolkit import QueryBuilder
|
|
288
|
+
|
|
289
|
+
builder = QueryBuilder()
|
|
290
|
+
|
|
291
|
+
# 构建复杂查询
|
|
292
|
+
query = (builder
|
|
293
|
+
.table('orders')
|
|
294
|
+
.select('users.name', 'orders.total', 'orders.created_at')
|
|
295
|
+
.left_join('users', 'orders.user_id = users.id')
|
|
296
|
+
.where("orders.status = 'completed'")
|
|
297
|
+
.where("orders.total > 100")
|
|
298
|
+
.group_by('users.name')
|
|
299
|
+
.having('SUM(orders.total) > 1000')
|
|
300
|
+
.order_by('orders.total', 'DESC')
|
|
301
|
+
.limit(10)
|
|
302
|
+
.build())
|
|
303
|
+
|
|
304
|
+
print(query)
|
|
305
|
+
# SELECT users.name, orders.total, orders.created_at FROM orders
|
|
306
|
+
# LEFT JOIN users ON orders.user_id = users.id
|
|
307
|
+
# WHERE orders.status = 'completed' AND orders.total > 100
|
|
308
|
+
# GROUP BY users.name
|
|
309
|
+
# HAVING SUM(orders.total) > 1000
|
|
310
|
+
# ORDER BY orders.total DESC
|
|
311
|
+
# LIMIT 10
|
|
312
|
+
|
|
313
|
+
# 使用查询
|
|
314
|
+
with client:
|
|
315
|
+
results = client.execute(query)
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
#### 批量操作
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
from db_toolkit.clients.sqlite import SQLiteClient
|
|
322
|
+
from db_toolkit.mixins import BatchOperationsMixin
|
|
323
|
+
|
|
324
|
+
# 创建扩展客户端
|
|
325
|
+
class ExtendedClient(SQLiteClient, BatchOperationsMixin):
|
|
326
|
+
pass
|
|
327
|
+
|
|
328
|
+
config = {'database': 'app.db'}
|
|
329
|
+
|
|
330
|
+
with ExtendedClient(config) as client:
|
|
331
|
+
# 批量插入
|
|
332
|
+
users = [
|
|
333
|
+
{'name': f'User{i}', 'email': f'user{i}@example.com'}
|
|
334
|
+
for i in range(100)
|
|
335
|
+
]
|
|
336
|
+
results = client.batch_insert('users', users, chunk_size=20)
|
|
337
|
+
|
|
338
|
+
# 批量更新
|
|
339
|
+
updates = [
|
|
340
|
+
{'data': {'status': 'active'}, 'condition': {'id': i}}
|
|
341
|
+
for i in range(1, 51)
|
|
342
|
+
]
|
|
343
|
+
count = client.batch_update('users', updates)
|
|
344
|
+
|
|
345
|
+
# 批量删除
|
|
346
|
+
conditions = [{'id': i} for i in range(51, 101)]
|
|
347
|
+
count = client.batch_delete('users', conditions)
|
|
348
|
+
|
|
349
|
+
# Upsert (插入或更新)
|
|
350
|
+
client.upsert('users', {
|
|
351
|
+
'email': 'alice@example.com',
|
|
352
|
+
'name': 'Alice Updated',
|
|
353
|
+
'status': 'active'
|
|
354
|
+
}, unique_fields=['email'])
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### 事务管理
|
|
358
|
+
|
|
359
|
+
```python
|
|
360
|
+
from db_toolkit.clients.postgresql import PostgreSQLClient
|
|
361
|
+
from db_toolkit.mixins import TransactionMixin
|
|
362
|
+
|
|
363
|
+
class TransactionalClient(PostgreSQLClient, TransactionMixin):
|
|
364
|
+
pass
|
|
365
|
+
|
|
366
|
+
config = {
|
|
367
|
+
'host': 'localhost',
|
|
368
|
+
'user': 'postgres',
|
|
369
|
+
'password': 'password',
|
|
370
|
+
'database': 'mydb'
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
with TransactionalClient(config) as client:
|
|
374
|
+
# 方式1: 使用上下文管理器
|
|
375
|
+
try:
|
|
376
|
+
with client.transaction():
|
|
377
|
+
client.insert('orders', {'user_id': 1, 'total': 100})
|
|
378
|
+
client.update('users', {'balance': 900}, {'id': 1})
|
|
379
|
+
# 自动提交
|
|
380
|
+
except Exception as e:
|
|
381
|
+
# 自动回滚
|
|
382
|
+
print(f"Transaction failed: {e}")
|
|
383
|
+
|
|
384
|
+
# 方式2: 手动控制
|
|
385
|
+
try:
|
|
386
|
+
client.begin()
|
|
387
|
+
client.insert('logs', {'message': 'Order created'})
|
|
388
|
+
client.insert('logs', {'message': 'Balance updated'})
|
|
389
|
+
client.commit()
|
|
390
|
+
except Exception:
|
|
391
|
+
client.rollback()
|
|
392
|
+
|
|
393
|
+
# 方式3: 使用保存点 (PostgreSQL)
|
|
394
|
+
client.begin()
|
|
395
|
+
client.savepoint('sp1')
|
|
396
|
+
try:
|
|
397
|
+
client.insert('temp_data', {'value': 'test'})
|
|
398
|
+
# 出错...
|
|
399
|
+
raise Exception("Something went wrong")
|
|
400
|
+
except Exception:
|
|
401
|
+
client.rollback_to_savepoint('sp1')
|
|
402
|
+
client.commit()
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### 扩展自定义客户端
|
|
406
|
+
|
|
407
|
+
```python
|
|
408
|
+
from db_toolkit import BaseClient, ClientFactory
|
|
409
|
+
|
|
410
|
+
class CustomDBClient(BaseClient):
|
|
411
|
+
"""自定义数据库客户端"""
|
|
412
|
+
|
|
413
|
+
def connect(self) -> bool:
|
|
414
|
+
# 实现连接逻辑
|
|
415
|
+
self._connected = True
|
|
416
|
+
return True
|
|
417
|
+
|
|
418
|
+
def disconnect(self) -> bool:
|
|
419
|
+
self._connected = False
|
|
420
|
+
return True
|
|
421
|
+
|
|
422
|
+
def is_connected(self) -> bool:
|
|
423
|
+
return self._connected
|
|
424
|
+
|
|
425
|
+
def execute(self, query: str, params=None):
|
|
426
|
+
# 实现查询执行
|
|
427
|
+
return []
|
|
428
|
+
|
|
429
|
+
def insert(self, table: str, data: dict):
|
|
430
|
+
# 实现插入
|
|
431
|
+
return 1
|
|
432
|
+
|
|
433
|
+
def update(self, table: str, data: dict, condition: dict):
|
|
434
|
+
return 1
|
|
435
|
+
|
|
436
|
+
def delete(self, table: str, condition: dict):
|
|
437
|
+
return 1
|
|
438
|
+
|
|
439
|
+
def select(self, table: str, fields=None, condition=None,
|
|
440
|
+
limit=None, offset=None, order_by=None):
|
|
441
|
+
return []
|
|
442
|
+
|
|
443
|
+
# 注册自定义客户端
|
|
444
|
+
ClientFactory.register('custom_db', CustomDBClient)
|
|
445
|
+
|
|
446
|
+
# 使用自定义客户端
|
|
447
|
+
with create_client('custom_db', {}) as client:
|
|
448
|
+
results = client.select('my_table')
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### 异常处理
|
|
452
|
+
|
|
453
|
+
```python
|
|
454
|
+
from db_toolkit import create_client
|
|
455
|
+
from db_toolkit.exceptions import (
|
|
456
|
+
ConnectionError,
|
|
457
|
+
QueryError,
|
|
458
|
+
ConfigurationError,
|
|
459
|
+
TransactionError
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
try:
|
|
463
|
+
# 配置错误
|
|
464
|
+
client = create_client('invalid_type', {})
|
|
465
|
+
except ConfigurationError as e:
|
|
466
|
+
print(f"Configuration error: {e}")
|
|
467
|
+
|
|
468
|
+
try:
|
|
469
|
+
# 连接错误
|
|
470
|
+
config = {'host': 'invalid', 'user': 'user', 'password': 'pass', 'database': 'db'}
|
|
471
|
+
client = create_client('mysql', config)
|
|
472
|
+
client.connect()
|
|
473
|
+
except ConnectionError as e:
|
|
474
|
+
print(f"Connection error: {e}")
|
|
475
|
+
|
|
476
|
+
try:
|
|
477
|
+
# 查询错误
|
|
478
|
+
with create_client('sqlite', {'database': ':memory:'}) as client:
|
|
479
|
+
client.select('nonexistent_table')
|
|
480
|
+
except QueryError as e:
|
|
481
|
+
print(f"Query error: {e}")
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## 🧪 测试
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
# 运行所有测试
|
|
488
|
+
python tests.py
|
|
489
|
+
|
|
490
|
+
# 运行示例
|
|
491
|
+
python examples.py
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
## 📋 配置文件示例
|
|
495
|
+
|
|
496
|
+
```json
|
|
497
|
+
{
|
|
498
|
+
"databases": {
|
|
499
|
+
"production": {
|
|
500
|
+
"type": "postgresql",
|
|
501
|
+
"config": {
|
|
502
|
+
"host": "prod-server.com",
|
|
503
|
+
"port": 5432,
|
|
504
|
+
"user": "app_user",
|
|
505
|
+
"password": "secure_password",
|
|
506
|
+
"database": "prod_db"
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
"development": {
|
|
510
|
+
"type": "sqlite",
|
|
511
|
+
"config": {
|
|
512
|
+
"database": "./dev.db"
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
"cache": {
|
|
516
|
+
"type": "redis",
|
|
517
|
+
"config": {
|
|
518
|
+
"host": "localhost",
|
|
519
|
+
"port": 6379,
|
|
520
|
+
"db": 0
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
"default": "development"
|
|
525
|
+
}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## 🤝 贡献
|
|
529
|
+
|
|
530
|
+
欢迎提交Issue和Pull Request!
|
|
531
|
+
|
|
532
|
+
## 🗺️ 路线图
|
|
533
|
+
|
|
534
|
+
- [ ] 连接池支持
|
|
535
|
+
- [ ] 异步操作支持
|
|
536
|
+
- [ ] 数据迁移工具
|
|
537
|
+
- [ ] ORM功能
|
|
538
|
+
- [ ] 更多数据库支持(CockroachDB、Cassandra等)
|
|
539
|
+
- [ ] 性能监控和分析
|
|
540
|
+
- [ ] 查询缓存
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
db_toolkit/__init__.py,sha256=eH0OhXTpSv2AxMjmeJ98cEB9m4KWEO2x-BPkh2bQBNQ,3182
|
|
2
|
+
db_toolkit/clients/__init__.py,sha256=0d671uA_Yd9XtWnKrjcU6KeYpP8yMt0Doo6REfEBXdA,437
|
|
3
|
+
db_toolkit/clients/mongodb.py,sha256=9rfHxAorEPOc_0Hhy244JIHoRixfeFHVZYVu556W2PU,8674
|
|
4
|
+
db_toolkit/clients/mysql.py,sha256=_FTsoTZyMbGmrP852TtZGAa0ZLgTjtz-JFhsTQKRv44,5076
|
|
5
|
+
db_toolkit/clients/postgresql.py,sha256=RKsgb6oQ6QsjdzRNexM5lufuwT67siKyXxlMwQfk5OA,5480
|
|
6
|
+
db_toolkit/clients/redis.py,sha256=7EQdIYs0j3KQ5bPiN-bO7YXIhbfM1wxk0aunw2ePRzI,10470
|
|
7
|
+
db_toolkit/clients/sqlite.py,sha256=ONHJWT04V9ghraZDaetJtuP_4aTm3fc0bicFvzyXyds,5157
|
|
8
|
+
db_toolkit/clients/supabase.py,sha256=1GhOJTfxECvh_FOX_H4UFLSPcf5u7eTDi-RIuPWJAAQ,8026
|
|
9
|
+
db_toolkit/core/__init__.py,sha256=_88NUWnp7Iqulx8O8bGubJoYpfbwvYqu2yvLKklwjUo,165
|
|
10
|
+
db_toolkit/core/base.py,sha256=JiEskSP7gbF65YzC6HziTHhkUhCG9eqFGbbq-JmCTlk,4738
|
|
11
|
+
db_toolkit/core/sql_base.py,sha256=JZ5aZ_3ezL20GTu5o5AjUd8qrauHMUEN1j6OxQE7QOg,4914
|
|
12
|
+
db_toolkit/exceptions/__init__.py,sha256=bjfhL2Ln0O2lnk723a02-XkLhgYwG_ZF_o-MRz6GSw8,618
|
|
13
|
+
db_toolkit/mixins/__init__.py,sha256=jf9zSWIKeGzwx0r8hTdHDPmi_duXGNXmA4UUuN_uDFs,216
|
|
14
|
+
db_toolkit/mixins/batch_ops.py,sha256=A4vDkKHe5bPFBmbadwgDUBdviQ02vFnPx32byoez6HY,6047
|
|
15
|
+
db_toolkit/mixins/transaction.py,sha256=uUsmwQydhAPJxoFgd00XitmNxuqF8ik12xt2XzEdK-0,6465
|
|
16
|
+
db_toolkit/utils/__init__.py,sha256=AcW9om61r-2ejmSD-PB1klHIkmedb-SkCksvxzk9HOI,306
|
|
17
|
+
db_toolkit/utils/config.py,sha256=_I7CcYPSX1H9guFmscUle-vAMe-Ya1NrpD_PmnLV24g,8235
|
|
18
|
+
db_toolkit/utils/factory.py,sha256=_qKIag_WG5vE2nzO0juniMni1RHFy7oSl2YGvbmCTes,5069
|
|
19
|
+
db_toolkit/utils/query_builder.py,sha256=YuzUuPsC57HiksUZv5N2aelw6auXPpxToI6vO7K54qk,8489
|
|
20
|
+
db_client_toolkit-0.0.1.dist-info/METADATA,sha256=v01KRVQe6rOWBrE4incHpXSAo2eTqEUFihN-HnE1fWA,12993
|
|
21
|
+
db_client_toolkit-0.0.1.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
|
|
22
|
+
db_client_toolkit-0.0.1.dist-info/RECORD,,
|
db_toolkit/__init__.py
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Database Toolkit - 通用数据库客户端工具包
|
|
3
|
+
|
|
4
|
+
一个强大且易用的Python数据库客户端,支持多种数据库类型,提供统一的API接口。
|
|
5
|
+
|
|
6
|
+
支持的数据库:
|
|
7
|
+
- MySQL
|
|
8
|
+
- PostgreSQL
|
|
9
|
+
- SQLite
|
|
10
|
+
- MongoDB
|
|
11
|
+
- Redis
|
|
12
|
+
- Supabase
|
|
13
|
+
|
|
14
|
+
基础使用:
|
|
15
|
+
>>> from db_toolkit import create_client
|
|
16
|
+
>>>
|
|
17
|
+
>>> config = {'database': 'test.db'}
|
|
18
|
+
>>> with create_client('sqlite', config) as client:
|
|
19
|
+
... results = client.select('users')
|
|
20
|
+
|
|
21
|
+
高级功能:
|
|
22
|
+
>>> from db_toolkit import ConfigManager, QueryBuilder
|
|
23
|
+
>>>
|
|
24
|
+
>>> # 配置管理
|
|
25
|
+
>>> manager = ConfigManager('db_config.json')
|
|
26
|
+
>>> client = manager.get_client('production')
|
|
27
|
+
>>>
|
|
28
|
+
>>> # SQL构建器
|
|
29
|
+
>>> builder = QueryBuilder()
|
|
30
|
+
>>> query = builder.table('users').select('*').where('age > 18').build()
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
__version__ = '2.0.0'
|
|
34
|
+
__author__ = 'Database Toolkit Team'
|
|
35
|
+
|
|
36
|
+
import logging
|
|
37
|
+
|
|
38
|
+
# 配置日志
|
|
39
|
+
logging.basicConfig(
|
|
40
|
+
level=logging.INFO,
|
|
41
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# 导出核心类
|
|
45
|
+
from .core import BaseClient, SQLBaseClient
|
|
46
|
+
|
|
47
|
+
# 导出所有客户端
|
|
48
|
+
from .clients import (
|
|
49
|
+
MySQLClient,
|
|
50
|
+
PostgreSQLClient,
|
|
51
|
+
SQLiteClient,
|
|
52
|
+
MongoDBClient,
|
|
53
|
+
RedisClient,
|
|
54
|
+
SupabaseClient,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# 导出工具类
|
|
58
|
+
from .utils import (
|
|
59
|
+
ClientFactory,
|
|
60
|
+
create_client,
|
|
61
|
+
ConfigManager,
|
|
62
|
+
QueryBuilder,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# 导出混入类
|
|
66
|
+
from .mixins import (
|
|
67
|
+
BatchOperationsMixin,
|
|
68
|
+
TransactionMixin,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# 导出异常
|
|
72
|
+
from .exceptions import (
|
|
73
|
+
DatabaseError,
|
|
74
|
+
ConnectionError,
|
|
75
|
+
QueryError,
|
|
76
|
+
ConfigurationError,
|
|
77
|
+
ValidationError,
|
|
78
|
+
NotSupportedError,
|
|
79
|
+
TransactionError,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# 定义公开API
|
|
83
|
+
__all__ = [
|
|
84
|
+
# 版本信息
|
|
85
|
+
'__version__',
|
|
86
|
+
'__author__',
|
|
87
|
+
|
|
88
|
+
# 核心类
|
|
89
|
+
'BaseClient',
|
|
90
|
+
'SQLBaseClient',
|
|
91
|
+
|
|
92
|
+
# 客户端
|
|
93
|
+
'MySQLClient',
|
|
94
|
+
'PostgreSQLClient',
|
|
95
|
+
'SQLiteClient',
|
|
96
|
+
'MongoDBClient',
|
|
97
|
+
'RedisClient',
|
|
98
|
+
'SupabaseClient',
|
|
99
|
+
|
|
100
|
+
# 工具类
|
|
101
|
+
'ClientFactory',
|
|
102
|
+
'create_client',
|
|
103
|
+
'ConfigManager',
|
|
104
|
+
'QueryBuilder',
|
|
105
|
+
|
|
106
|
+
# 混入类
|
|
107
|
+
'BatchOperationsMixin',
|
|
108
|
+
'TransactionMixin',
|
|
109
|
+
|
|
110
|
+
# 异常
|
|
111
|
+
'DatabaseError',
|
|
112
|
+
'ConnectionError',
|
|
113
|
+
'QueryError',
|
|
114
|
+
'ConfigurationError',
|
|
115
|
+
'ValidationError',
|
|
116
|
+
'NotSupportedError',
|
|
117
|
+
'TransactionError',
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def get_version() -> str:
|
|
122
|
+
"""获取版本号"""
|
|
123
|
+
return __version__
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def list_available_databases() -> list:
|
|
127
|
+
"""列出所有可用的数据库类型"""
|
|
128
|
+
return ClientFactory.list_available()
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def configure_logging(level: int = logging.INFO,
|
|
132
|
+
format: str = None,
|
|
133
|
+
handlers: list = None) -> None:
|
|
134
|
+
"""
|
|
135
|
+
配置日志
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
level: 日志级别
|
|
139
|
+
format: 日志格式
|
|
140
|
+
handlers: 日志处理器列表
|
|
141
|
+
"""
|
|
142
|
+
logger = logging.getLogger('db_toolkit')
|
|
143
|
+
logger.setLevel(level)
|
|
144
|
+
|
|
145
|
+
if format:
|
|
146
|
+
formatter = logging.Formatter(format)
|
|
147
|
+
for handler in logger.handlers:
|
|
148
|
+
handler.setFormatter(formatter)
|
|
149
|
+
|
|
150
|
+
if handlers:
|
|
151
|
+
logger.handlers = handlers
|