mlmongo 1.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.
mlmongo/__init__.py ADDED
@@ -0,0 +1 @@
1
+ from .sync import Mongoer, MongoerChild
mlmongo/asyncs.py ADDED
@@ -0,0 +1,150 @@
1
+ import asyncio
2
+ from typing import Any,AsyncGenerator
3
+ from pydantic import BaseModel
4
+ try:
5
+ from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorCollection
6
+ except:
7
+ raise ModuleNotFoundError('pip install motor')
8
+
9
+
10
+ def _limit(afunc):
11
+ async def _main(self:'AMongoer', *args, **kwargs):
12
+ async with self._sem:
13
+ return await afunc(self, *args, **kwargs)
14
+
15
+ return _main
16
+
17
+ def _limit_iterator(afunc):
18
+ async def _main(self:'AMongoer', *args, **kwargs):
19
+ async with self._sem:
20
+ async for result in afunc(self, *args, **kwargs):
21
+ yield result
22
+
23
+ return _main
24
+
25
+ class AMongoer:
26
+ def __init__(self, url:str, default_db:str, default_col:str, default_key_name:str=None, async_limit:int=300):
27
+ self.url = url
28
+ self.client=None
29
+ self.default_db=default_db
30
+ self.default_col=default_col
31
+ self.default_key_name=default_key_name
32
+ self._sem = asyncio.BoundedSemaphore(async_limit)
33
+
34
+ def _getClient(self):
35
+ client = AsyncIOMotorClient(self.url)
36
+ client.get_io_loop = asyncio.get_running_loop
37
+ return client
38
+
39
+ def getConnect(self, db: str=None, col:str=None)->AsyncIOMotorCollection:
40
+ if self.client is None: self.client=self._getClient()
41
+ return self.client[db or self.default_db][col or self.default_col]
42
+
43
+ async def client_reset(self):
44
+ if self.client: self.client.close()
45
+ self.client = self._getClient()
46
+
47
+ async def client_auto_reset(self, s=600):
48
+ while True:
49
+ await asyncio.sleep(s)
50
+ self.client.close()
51
+ self.client = self._getClient()
52
+
53
+ @_limit
54
+ async def find(self, query: dict, db:str=None, col:str=None, cig:dict=None, default_id:int=0)->dict|None:
55
+ if default_id==0: cig = {'_id':0, **cig} if cig else {'_id':0}
56
+ result = await self.getConnect(db,col).find_one(query or {}, cig or {})
57
+ return result
58
+
59
+ @_limit_iterator
60
+ async def find_all(self, query: dict=None, db:str=None, col:str=None, cig=None,
61
+ sort_map: dict[str, int]=None, skip:int=None, limit:int=None)->AsyncGenerator[dict, None]:
62
+ cursor = self.getConnect(db,col).find(query, {'_id':0, **cig} if cig else {'_id':0})
63
+ if sort_map: cursor=cursor.sort(sort_map)
64
+ if skip: cursor=cursor.skip(skip)
65
+ if limit: cursor=cursor.limit(limit)
66
+ async for dt in cursor:
67
+ yield dt
68
+
69
+ @_limit
70
+ async def find_onekey_all(self, key:str, query: dict=None, db:str=None, col:str=None)->list:
71
+ cursor = self.getConnect(db,col).find(query, {'_id':0, key:1})
72
+ return [dt[key] async for dt in cursor]
73
+
74
+ @_limit
75
+ async def find_onecol(self, key:str, query: dict, db:str=None, col:str=None, default=None):
76
+ dt = (await self.getConnect(db,col).find_one(query, {'_id':0, key:1})) or {}
77
+ return dt.get(key, default)
78
+
79
+ @_limit
80
+ async def count(self, query: dict=None, db:str=None, col:str=None)->int:
81
+ return await self.getConnect(db,col).count_documents(query)
82
+
83
+ @_limit
84
+ async def update_one(self, query: dict, data: BaseModel|dict, db:str=None, col:str=None, upsert=True)->dict:
85
+ return (await self.getConnect(db,col).update_one(query, {'$set': data.model_dump() if isinstance(data,BaseModel) else data}, upsert=upsert)).raw_result
86
+
87
+ @_limit
88
+ async def update_by_id(self, id:Any, data:BaseModel|dict, db:str=None, col:str=None, upsert=True, key_name:str=None):
89
+ assert key_name or self.default_key_name, '没有设置key_name'
90
+ return await self.update_one({key_name or self.default_key_name:id}, data, db=db, col=col, upsert=upsert)
91
+
92
+ @_limit
93
+ async def update(self, query: dict, dt:dict, db:str=None, col:str=None)->dict:
94
+ return (await self.getConnect(db,col).update_many(query, {'$set': dt})).raw_result
95
+
96
+ @_limit
97
+ async def del_field(self, query: dict, *fields: str, db:str=None, col:str=None)->dict:
98
+ assert fields
99
+ return (await self.getConnect(db,col).update_many(query, {'$unset':{f:'' for f in fields}})).raw_result
100
+
101
+ @_limit
102
+ async def pop(self, query: dict,db:str=None, col:str=None)->dict|None:
103
+ try:
104
+ dt = (await self.getConnect(db,col).find_one_and_delete(query)) or {}
105
+ dt.pop('_id', None)
106
+ return dt
107
+ except asyncio.exceptions.CancelledError as e:
108
+ raise e
109
+ except Exception as e:
110
+ return None
111
+
112
+ @_limit
113
+ async def insert(self, data: BaseModel|dict, db:str=None, col:str=None, **kwargs):
114
+ return await self.getConnect(db,col).insert_one(data.model_dump( **kwargs) if isinstance(data, BaseModel) else data)
115
+
116
+ @_limit
117
+ async def insert_many(self, datas: list[BaseModel|dict], db:str=None, col:str=None, **kwargs):
118
+ if not datas: return None
119
+ datas = [(data.model_dump(**kwargs) if isinstance(data, BaseModel) else data) for data in datas]
120
+ return await self.getConnect(db,col).insert_many(datas)
121
+
122
+ @_limit
123
+ async def delete(self, query: dict, db:str=None, col:str=None)->dict:
124
+ return (await self.getConnect(db,col).delete_many(query)).raw_result
125
+
126
+ def getChild(self, default_col:str)->'AMongoerChild':
127
+ return AMongoerChild(self, default_col)
128
+
129
+ class AMongoerChild(AMongoer):
130
+ def __init__(self, amer: AMongoer, default_col:str):
131
+ self._amer=amer
132
+ self.client=amer.client
133
+ self.default_db=amer.default_db
134
+ self.default_col=default_col
135
+ self.default_key_name=amer.default_key_name
136
+ self._sem = amer._sem
137
+
138
+ def _getClient(self):
139
+ self._amer.client = self._amer._getClient()
140
+ return self._amer.client
141
+
142
+ def getConnect(self, db: str=None, col:str=None)->AsyncIOMotorCollection:
143
+ if self.client is None: self.client=self._getClient()
144
+ return self.client[db or self.default_db][col or self.default_col]
145
+
146
+ async def client_reset(self):
147
+ raise ValueError('子类对象不能调用该方法')
148
+
149
+ async def client_auto_reset(self, **_):
150
+ raise ValueError('子类对象不能调用该方法')
mlmongo/sync.py ADDED
@@ -0,0 +1,121 @@
1
+ import asyncio
2
+ from threading import Thread, Lock
3
+ import time
4
+ from typing import Any, Generator
5
+ from pydantic import BaseModel
6
+ from pymongo import MongoClient
7
+
8
+
9
+ class Mongoer:
10
+ def __init__(self, url:str, default_db:str, default_col:str, default_key_name:str=None):
11
+ self.url = url
12
+ self.client=None
13
+ self._lock = Lock()
14
+ self.default_db=default_db
15
+ self.default_col=default_col
16
+ self.default_key_name=default_key_name
17
+
18
+ def _getClient(self):
19
+ client = MongoClient(self.url)
20
+ return client
21
+
22
+ def getConnect(self, db: str=None, col:str=None):
23
+ if self.client is None:
24
+ with self._lock:
25
+ self.client=self._getClient()
26
+ return self.client[db or self.default_db][col or self.default_col]
27
+
28
+ def client_auto_reset(self, s=600):
29
+ def temp():
30
+ while True:
31
+ time.sleep(s)
32
+ with self._lock:
33
+ self.client.close()
34
+ self.client = self._getClient()
35
+ Thread(target=temp, daemon=True).start()
36
+
37
+ def find(self, query: dict, db:str=None, col:str=None, cig:dict=None, default_id:int=0)->dict|None:
38
+ if default_id==0: cig = {'_id':0, **cig} if cig else {'_id':0}
39
+ result = self.getConnect(db,col).find_one(query or {}, cig or {})
40
+ return result
41
+
42
+ def find_all(self, query: dict=None, db:str=None, col:str=None, cig=None,
43
+ sort_map: dict[str, int]=None, skip:int=None, limit:int=None)->Generator[dict, None, None]:
44
+ cursor = self.getConnect(db,col).find(query, {'_id':0, **cig} if cig else {'_id':0})
45
+ if sort_map: cursor=cursor.sort(sort_map)
46
+ if skip: cursor=cursor.skip(skip)
47
+ if limit: cursor=cursor.limit(limit)
48
+ for dt in cursor:
49
+ yield dt
50
+
51
+ def find_onekey_all(self, key:str, query: dict=None, db:str=None, col:str=None)->list:
52
+ cursor = self.getConnect(db,col).find(query, {'_id':0, key:1})
53
+ return [dt[key] for dt in cursor]
54
+
55
+ def find_onecol(self, key:str, query: dict=None, db:str=None, col:str=None, default=None):
56
+ dt = (self.getConnect(db,col).find_one(query, {'_id':0, key:1})) or {}
57
+ return dt.get(key, default)
58
+
59
+ def count(self, query: dict=None, db:str=None, col:str=None,)->int:
60
+ return self.getConnect(db,col).count_documents(query)
61
+
62
+ def update_one(self, query: dict, data: BaseModel|dict, db:str=None, col:str=None, upsert=True)->dict:
63
+ return self.getConnect(db,col).update_one(query, {'$set': data.model_dump() if isinstance(data,BaseModel) else data}, upsert=upsert).raw_result
64
+
65
+ def update_by_id(self, id:Any, data:BaseModel|dict, db:str=None, col:str=None, upsert=True, key_name:str=None):
66
+ assert key_name or self.default_key_name, '没有设置key_name'
67
+ return self.update_one({key_name or self.default_key_name:id}, data, db=db, col=col, upsert=upsert)
68
+
69
+ def update(self, query: dict, dt: dict, db:str=None, col:str=None)->dict:
70
+ return self.getConnect(db,col).update_many(query, {'$set': dt}).raw_result
71
+
72
+ def del_field(self, query: dict, *fields: str, db:str=None, col:str=None)->dict:
73
+ assert fields
74
+ return self.getConnect(db,col).update_many(query, {'$unset':{f:'' for f in fields}}).raw_result
75
+
76
+ def pop(self, query: dict,db:str=None, col:str=None)->dict|None:
77
+ try:
78
+ dt = self.getConnect(db,col).find_one_and_delete(query) or {}
79
+ dt.pop('_id', None)
80
+ return dt
81
+ except asyncio.exceptions.CancelledError as e:
82
+ raise e
83
+ except Exception as e:
84
+ return None
85
+
86
+ def insert(self, data: BaseModel|dict, db:str=None, col:str=None, **kwargs):
87
+ return self.getConnect(db,col).insert_one(data.model_dump( **kwargs) if isinstance(data, BaseModel) else data)
88
+
89
+ def insert_many(self, datas: list[BaseModel|dict], db:str=None, col:str=None, **kwargs):
90
+ if not datas: return None
91
+ datas = [(data.model_dump(**kwargs) if isinstance(data, BaseModel) else data) for data in datas]
92
+ return self.getConnect(db,col).insert_many(datas)
93
+
94
+ def delete(self, query: dict, db:str=None, col:str=None)->dict:
95
+ return self.getConnect(db,col).delete_many(query).raw_result
96
+
97
+ def getChild(self, default_col:str)->'MongoerChild':
98
+ return MongoerChild(self, default_col)
99
+
100
+ class MongoerChild(Mongoer):
101
+ def __init__(self, mer: Mongoer, default_col:str):
102
+ self._amer=mer
103
+ self.client=mer.client
104
+ self.default_db=mer.default_db
105
+ self.default_col=default_col
106
+ self.default_key_name=mer.default_key_name
107
+ self._lock = mer._lock
108
+
109
+ def _getClient(self):
110
+ self._amer.client = self._amer._getClient()
111
+ return self._amer.client
112
+
113
+ def getConnect(self, db: str=None, col:str=None):
114
+ if self.client is None: self.client=self._getClient()
115
+ return self.client[db or self.default_db][col or self.default_col]
116
+
117
+ def client_reset(self):
118
+ raise ValueError('子类对象不能调用该方法')
119
+
120
+ def client_auto_reset(self, **_):
121
+ raise ValueError('子类对象不能调用该方法')
@@ -0,0 +1,19 @@
1
+ Metadata-Version: 2.4
2
+ Name: mlmongo
3
+ Version: 1.0.0
4
+ Summary: mongodb数据库操作工具类
5
+ Home-page: https://www.python.org
6
+ Author: mengling
7
+ Author-email: 1321443305@qq.com
8
+ Requires-Python: >=3.8
9
+ Requires-Dist: pymongo
10
+ Requires-Dist: pydantic
11
+ Provides-Extra: all
12
+ Requires-Dist: motor; extra == "all"
13
+ Dynamic: author
14
+ Dynamic: author-email
15
+ Dynamic: home-page
16
+ Dynamic: provides-extra
17
+ Dynamic: requires-dist
18
+ Dynamic: requires-python
19
+ Dynamic: summary
@@ -0,0 +1,7 @@
1
+ mlmongo/__init__.py,sha256=cesH70lLQoM_qLpj9RBRTkfgCk1rZuWANL7a_92P1Yk,39
2
+ mlmongo/asyncs.py,sha256=4igFtzLh1d3pEsfFqGuJOBPAwYS70bXA6YJWOLmtGWs,6269
3
+ mlmongo/sync.py,sha256=wwTVAvDfSrr3MCHplsDiIQW-aWCe8S5MzZspHynvy3M,5282
4
+ mlmongo-1.0.0.dist-info/METADATA,sha256=amtm9RIdW4pU4T4NcOv0uwQ5_7MDuKuFl4TSj_sUFxk,448
5
+ mlmongo-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
+ mlmongo-1.0.0.dist-info/top_level.txt,sha256=0QntA4yS1rOX5C2b0qWL_c0VL1fooUWGAdnP6afYq0g,8
7
+ mlmongo-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ mlmongo