cloudoll 3.0.6__tar.gz → 3.0.7__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.
Files changed (50) hide show
  1. {cloudoll-3.0.6 → cloudoll-3.0.7}/PKG-INFO +1 -1
  2. cloudoll-3.0.7/cloudoll/__init__.py +1 -0
  3. cloudoll-3.0.7/cloudoll/orm/__init__.py +44 -0
  4. cloudoll-3.0.7/cloudoll/orm/awsmysql.py +79 -0
  5. cloudoll-3.0.7/cloudoll/orm/awspostgres.py +93 -0
  6. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/orm/base.py +3 -5
  7. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/orm/model.py +9 -5
  8. cloudoll-3.0.7/cloudoll/orm/mysql.py +112 -0
  9. cloudoll-3.0.7/cloudoll/orm/postgres.py +116 -0
  10. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/orm/test_sql.py +1 -1
  11. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/web/core.py +51 -28
  12. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll.egg-info/PKG-INFO +1 -1
  13. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll.egg-info/SOURCES.txt +2 -0
  14. {cloudoll-3.0.6 → cloudoll-3.0.7}/pyproject.toml +1 -1
  15. cloudoll-3.0.6/cloudoll/__init__.py +0 -1
  16. cloudoll-3.0.6/cloudoll/orm/__init__.py +0 -247
  17. cloudoll-3.0.6/cloudoll/orm/mysql.py +0 -82
  18. cloudoll-3.0.6/cloudoll/orm/postgres.py +0 -68
  19. {cloudoll-3.0.6 → cloudoll-3.0.7}/LICENSE +0 -0
  20. {cloudoll-3.0.6 → cloudoll-3.0.7}/README.md +0 -0
  21. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/__main__.py +0 -0
  22. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/cli.py +0 -0
  23. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/clitool/__init__.py +0 -0
  24. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/clitool/cli_main.py +0 -0
  25. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/clitool/m2d.py +0 -0
  26. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/clitool/process.py +0 -0
  27. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/clitool/spinner.py +0 -0
  28. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/clitool/watch.py +0 -0
  29. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/logging/__init__.py +0 -0
  30. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/mail/__init__.py +0 -0
  31. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/mail/smtp.py +0 -0
  32. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/orm/err.py +0 -0
  33. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/orm/field.py +0 -0
  34. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/orm/parse.py +0 -0
  35. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/template/__init__.py +0 -0
  36. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/utils/__init__.py +0 -0
  37. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/utils/common.py +0 -0
  38. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/utils/snowflake.py +0 -0
  39. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/web/__init__.py +0 -0
  40. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/web/exception.py +0 -0
  41. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/web/html.py +0 -0
  42. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/web/jwt.py +0 -0
  43. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/web/requests.py +0 -0
  44. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll/web/settings.py +0 -0
  45. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll.egg-info/dependency_links.txt +0 -0
  46. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll.egg-info/entry_points.txt +0 -0
  47. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll.egg-info/requires.txt +0 -0
  48. {cloudoll-3.0.6 → cloudoll-3.0.7}/cloudoll.egg-info/top_level.txt +0 -0
  49. {cloudoll-3.0.6 → cloudoll-3.0.7}/setup.cfg +0 -0
  50. {cloudoll-3.0.6 → cloudoll-3.0.7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudoll
3
- Version: 3.0.6
3
+ Version: 3.0.7
4
4
  Summary: Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use.
5
5
  Home-page: https://github.com/smallerqiu/cloudoll-py
6
6
  Author: Qiu
@@ -0,0 +1 @@
1
+ __version__ = "3.0.7"
@@ -0,0 +1,44 @@
1
+ from redis import asyncio as aioredis
2
+ from cloudoll.orm.parse import parse_coon
3
+ import aiopg as pg
4
+ from .mysql import Mysql
5
+ from .postgres import Postgres
6
+ from .awspostgres import AwsPostgres
7
+ from .awsmysql import AwsMysql
8
+
9
+ __all__ = ["create_engine"]
10
+
11
+
12
+ async def create_engine(**kw):
13
+ url = kw.get("url")
14
+ driver = None
15
+ configs = {}
16
+ query = {}
17
+
18
+ if url is not None:
19
+ configs, query = parse_coon(url)
20
+ driver = configs["type"]
21
+ else:
22
+ driver = kw.get("type")
23
+ configs = kw
24
+
25
+ # info("DB Config:", configs, query)
26
+
27
+ if driver == "mysql":
28
+ return await Mysql().create_engine(**configs, **query)
29
+ elif driver == "aws-mysql":
30
+ return await AwsMysql().create_engine(**configs, **query)
31
+ elif driver in ["aws-postgres", "aws-postgressql"]:
32
+ return await AwsPostgres().create_engine(**configs, **query)
33
+ elif driver in ["postgres", "postgressql"]:
34
+ return await Postgres().create_engine(**configs, **query)
35
+ elif driver in ["redis", "rediss"]:
36
+ """
37
+ redis://[[username]:[password]]@localhost:6379/0
38
+ rediss://[[username]:[password]]@localhost:6379/0
39
+ """
40
+ if url is None:
41
+ url = f"{driver}://{configs['username']}:{configs['password']}@{configs['host']}:{configs['port']}/{configs['db']}"
42
+ return await aioredis.from_url(url, **query)
43
+ else:
44
+ raise ValueError("Not support this database type.")
@@ -0,0 +1,79 @@
1
+ from mysql.connector import Connect
2
+
3
+ from aws_advanced_python_wrapper import AwsWrapperConnection
4
+ from aws_advanced_python_wrapper.connection_provider import ConnectionProviderManager
5
+ from aws_advanced_python_wrapper.sql_alchemy_connection_provider import (
6
+ SqlAlchemyPooledConnectionProvider,
7
+ )
8
+
9
+ from cloudoll.orm.base import MeteBase, QueryTypes
10
+ from cloudoll.logging import info, error
11
+
12
+
13
+ class AwsMysql(MeteBase):
14
+ def __init__(self):
15
+ self.driver = "aws-mysql"
16
+ provider = SqlAlchemyPooledConnectionProvider()
17
+ ConnectionProviderManager.set_connection_provider(provider)
18
+
19
+ async def close(self):
20
+ ConnectionProviderManager.release_resources()
21
+
22
+ async def create_engine(self, **kw):
23
+ self._dsn = f"host={kw.get("host")} database={kw.get("db")} user={kw.get("username")} password={kw.get("password","")}"
24
+ self._params = {
25
+ "plugins": kw.get("plugins", ""),
26
+ "wrapper_dialect": kw.get("wrapper_dialect", ""),
27
+ "autocommit": True,
28
+ }
29
+ return self
30
+
31
+ async def query(self, sql, params=None, query_type=QueryTypes.ONE, size=10):
32
+ sql = sql.replace("?", "%s")
33
+ try:
34
+ with AwsWrapperConnection.connect(
35
+ Connect, self._dsn, **self._params
36
+ ) as conn:
37
+ with conn.cursor() as cursor:
38
+ if (
39
+ query_type == QueryTypes.CREATEBATCH
40
+ or query_type == QueryTypes.UPDATEBATCH
41
+ ):
42
+ cursor.executemany(sql, params)
43
+ else:
44
+ cursor.execute(sql, params)
45
+
46
+ if query_type == QueryTypes.ALL:
47
+ return cursor.fetchall()
48
+ elif query_type == QueryTypes.ONE:
49
+ return cursor.fetchone()
50
+ elif query_type == QueryTypes.MANY:
51
+ return cursor.fetchmany(size)
52
+ elif query_type == QueryTypes.COUNT:
53
+ rows = cursor.fetchone()
54
+ count = 0
55
+ if rows is None:
56
+ return count
57
+ for row in rows:
58
+ count = rows[row]
59
+ return count
60
+ elif query_type == QueryTypes.GROUP_COUNT:
61
+ result = cursor.fetchall()
62
+ return 0 if not result else len(result)
63
+ elif query_type == QueryTypes.CREATE:
64
+ result = cursor.rowcount > 0
65
+ id = cursor.target_cursor.lastrowid
66
+ return result, id
67
+ elif query_type == QueryTypes.CREATEBATCH:
68
+ count = cursor.rowcount
69
+ id = cursor.target_cursor.lastrowid
70
+ return count, id
71
+ elif query_type == QueryTypes.UPDATE:
72
+ return cursor.rowcount > 0
73
+ elif query_type == QueryTypes.UPDATEBATCH:
74
+ return cursor.rowcount
75
+ elif query_type == QueryTypes.DELETE:
76
+ return cursor.rowcount > 0
77
+ except Exception as e:
78
+ error(f"[AWS PG] query error: {e}, SQL: {sql}")
79
+ raise e
@@ -0,0 +1,93 @@
1
+ import psycopg
2
+ from aws_advanced_python_wrapper import AwsWrapperConnection
3
+ from aws_advanced_python_wrapper.connection_provider import ConnectionProviderManager
4
+ from aws_advanced_python_wrapper.sql_alchemy_connection_provider import (
5
+ SqlAlchemyPooledConnectionProvider,
6
+ )
7
+
8
+ from cloudoll.orm.base import MeteBase, QueryTypes
9
+ from cloudoll.logging import info, error
10
+
11
+
12
+ class AwsPostgres(MeteBase):
13
+ def __init__(self):
14
+ self.driver = "aws-postgres"
15
+ provider = SqlAlchemyPooledConnectionProvider()
16
+ ConnectionProviderManager.set_connection_provider(provider)
17
+
18
+ async def close(self):
19
+ ConnectionProviderManager.release_resources()
20
+
21
+ async def create_engine(self, **kw):
22
+ self._dsn = f"host={kw.get("host")} dbname={kw.get("db")} user={kw.get("username")} password={kw.get("username")}"
23
+ self._params = {
24
+ "plugins": kw.get("plugins", ""),
25
+ "wrapper_dialect": kw.get("wrapper_dialect"),
26
+ "autocommit": True,
27
+ }
28
+ return self
29
+
30
+ async def query(self, sql, params=None, query_type=QueryTypes.ONE, size=10):
31
+ sql = sql.replace("?", "%s").replace("`", '"')
32
+ try:
33
+ with AwsWrapperConnection.connect(
34
+ psycopg.Connection.connect, self._dsn, **self._params
35
+ ) as conn:
36
+ with conn.cursor() as cursor:
37
+ if (
38
+ query_type == QueryTypes.CREATEBATCH
39
+ or query_type == QueryTypes.UPDATEBATCH
40
+ ):
41
+ cursor.executemany(sql, params)
42
+ else:
43
+ cursor.execute(sql, params)
44
+
45
+ result = None
46
+
47
+ if query_type == QueryTypes.ALL and cursor.description is not None:
48
+ columns = [desc[0] for desc in cursor.target_cursor.description]
49
+ rows = cursor.fetchall()
50
+ result = [dict(zip(columns, row)) for row in rows]
51
+ return result
52
+ elif (
53
+ query_type == QueryTypes.ONE and cursor.description is not None
54
+ ):
55
+ columns = [desc[0] for desc in cursor.target_cursor.description]
56
+ row = cursor.fetchone()
57
+ result = dict(zip(columns, row)) if row else {}
58
+ return result
59
+ elif (
60
+ query_type == QueryTypes.MANY and cursor.description is not None
61
+ ):
62
+ columns = [desc[0] for desc in cursor.target_cursor.description]
63
+ rows = cursor.fetchmany(size)
64
+ result = [dict(zip(columns, row)) for row in rows]
65
+ return result
66
+ elif query_type == QueryTypes.COUNT:
67
+ result = cursor.fetchone()
68
+ count = 0
69
+ if result is None:
70
+ return count
71
+ for value in result:
72
+ count = value
73
+ return count
74
+ elif query_type == QueryTypes.GROUP_COUNT:
75
+ result = cursor.fetchall()
76
+ return 0 if not result else len(result)
77
+ elif query_type == QueryTypes.CREATE:
78
+ result = cursor.rowcount > 0
79
+ id = cursor.target_cursor.lastrowid
80
+ return result, id
81
+ elif query_type == QueryTypes.CREATEBATCH:
82
+ count = cursor.rowcount
83
+ id = cursor.target_cursor.lastrowid
84
+ return count, id
85
+ elif query_type == QueryTypes.UPDATE:
86
+ return cursor.rowcount > 0
87
+ elif query_type == QueryTypes.UPDATEBATCH:
88
+ return cursor.rowcount
89
+ elif query_type == QueryTypes.DELETE:
90
+ return cursor.rowcount > 0
91
+ except Exception as e:
92
+ error(f"[AWS PG] query error: {e}, SQL: {sql}")
93
+ raise e
@@ -19,8 +19,8 @@ class QueryTypes(Enum):
19
19
 
20
20
 
21
21
  class MeteBase:
22
- def __init__(self):
23
- self.pool: Optional[MyPool | PGPool] = None
22
+ # def __init__(self):
23
+ # self.pool: Optional[MyPool | PGPool] = None
24
24
  # self.cursor: Optional[Cursor] = None
25
25
  # self.conn: Optional[Connection] = None
26
26
 
@@ -28,9 +28,7 @@ class MeteBase:
28
28
  await self.close()
29
29
 
30
30
  async def close(self):
31
- if self.pool:
32
- self.pool.close()
33
- await self.pool.wait_closed()
31
+ ...
34
32
 
35
33
  # async def begin_transaction(self):
36
34
  # conn = await self._set_conn()
@@ -150,14 +150,18 @@ class Model(metaclass=ModelMetaclass):
150
150
  @classmethod
151
151
  def use(cls, pool=None):
152
152
  cls.__pool__ = pool
153
- cls.__ispg = pool.driver == "postgres" if pool else False
153
+ cls.__is_pg = (
154
+ pool.driver in ["postgres", "postgressql", "aws-postgres"]
155
+ if pool
156
+ else False
157
+ )
154
158
  return cls()
155
159
 
156
160
  def select(cls, *args):
157
161
  cols = []
158
162
  for col in args:
159
163
  if isinstance(col, Field):
160
- cols.append(col.name if cls.__ispg else col.full_name)
164
+ cols.append(col.name if cls.__is_pg else col.full_name)
161
165
  elif isinstance(col, Function):
162
166
  q, p = col.sql()
163
167
  cols.append(q)
@@ -200,7 +204,7 @@ class Model(metaclass=ModelMetaclass):
200
204
  if isinstance(f, str):
201
205
  by.append(f)
202
206
  else:
203
- by.append(f"{f.lhs.name if self.__ispg else f.lhs.full_name} {f.op}")
207
+ by.append(f"{f.lhs.name if self.__is_pg else f.lhs.full_name} {f.op}")
204
208
  if self.__order_by__ is not None:
205
209
  by = self.__order_by__ + by
206
210
  self.__order_by__ = by
@@ -209,7 +213,7 @@ class Model(metaclass=ModelMetaclass):
209
213
  def group_by(self, *args):
210
214
  by = []
211
215
  for f in args:
212
- by.append(f.name if self.__ispg else f.full_name)
216
+ by.append(f.name if self.__is_pg else f.full_name)
213
217
  if self.__group_by__ is not None:
214
218
  by = self.__group_by__ + by
215
219
  self.__group_by__ = by
@@ -365,7 +369,7 @@ class Model(metaclass=ModelMetaclass):
365
369
  return await self.__pool__.all(sql, args)
366
370
 
367
371
  def _exchange_sql(self, sql: str):
368
- if self.__ispg:
372
+ if self.__is_pg:
369
373
  sql = sql.replace("CURDATE()", "CURRENT_DATE")
370
374
  sql = sql.replace("NOW()", "CURRENT_TIMESTAMP")
371
375
 
@@ -0,0 +1,112 @@
1
+ from typing import Any, Optional
2
+ import aiomysql
3
+ from cloudoll.logging import error
4
+ from cloudoll.orm.base import MeteBase, QueryTypes
5
+ from cloudoll.logging import info, error
6
+
7
+
8
+ class AttrDict(dict):
9
+ def __getattr__(self, name):
10
+ try:
11
+ return self[name]
12
+ except KeyError:
13
+ return None
14
+
15
+
16
+ class AttrDictCursor(aiomysql.DictCursor):
17
+ dict_type = AttrDict
18
+
19
+
20
+ class Mysql(MeteBase):
21
+ def __init__(self):
22
+ self.pool: aiomysql.Pool
23
+ self.driver = "mysql"
24
+
25
+ def __call__(self, *args: Any, **kwds: Any) -> Any:
26
+ self.__init__(*args, **kwds)
27
+ return self
28
+
29
+ async def close(self):
30
+ if self.pool:
31
+ self.pool.close()
32
+ await self.pool.wait_closed()
33
+
34
+ async def query(
35
+ self, sql, params=None, query_type: QueryTypes = QueryTypes.ONE, size: int = 10
36
+ ):
37
+ sql = sql.replace("?", "%s")
38
+ if not self.pool:
39
+ raise ValueError("must be create_engine first.")
40
+ if self.pool._closing or self.pool._closed:
41
+ return None
42
+ async with self.pool.acquire() as conn:
43
+ if conn.echo:
44
+ info("sql: %s , %s", sql, params)
45
+
46
+ async with conn.cursor() as cursor:
47
+ cursor: aiomysql.Cursor = cursor
48
+ if (
49
+ query_type == QueryTypes.CREATEBATCH
50
+ or query_type == QueryTypes.UPDATEBATCH
51
+ ):
52
+ await cursor.executemany(sql, params)
53
+ else:
54
+ await cursor.execute(sql, params)
55
+
56
+ await conn.commit()
57
+
58
+ if query_type == QueryTypes.ALL:
59
+ return await cursor.fetchall()
60
+ elif query_type == QueryTypes.ONE:
61
+ return await cursor.fetchone()
62
+ elif query_type == QueryTypes.MANY:
63
+ return await cursor.fetchmany(size)
64
+ elif query_type == QueryTypes.COUNT:
65
+ rows = await cursor.fetchone()
66
+ count = 0
67
+ if rows is None:
68
+ return count
69
+ for row in rows:
70
+ count = rows[row]
71
+ return count
72
+ elif query_type == QueryTypes.GROUP_COUNT:
73
+ result = await cursor.fetchall()
74
+ return 0 if not result else len(result)
75
+ elif query_type == QueryTypes.CREATE:
76
+ result = cursor.rowcount > 0
77
+ id = cursor.lastrowid
78
+ return result, id
79
+ elif query_type == QueryTypes.CREATEBATCH:
80
+ count = cursor.rowcount
81
+ id = cursor.lastrowid
82
+ return count, id
83
+ elif query_type == QueryTypes.UPDATE:
84
+ return cursor.rowcount > 0
85
+ elif query_type == QueryTypes.UPDATEBATCH:
86
+ return cursor.rowcount
87
+ elif query_type == QueryTypes.DELETE:
88
+ return cursor.rowcount > 0
89
+
90
+ self.pool.release(conn)
91
+
92
+ async def create_engine(self, loop=None, **kw):
93
+ try:
94
+ self.pool = await aiomysql.create_pool(
95
+ host=kw.get("host", "localhost"),
96
+ port=kw.get("port", 3306),
97
+ user=kw.get("username"),
98
+ password=str(kw.get("password", "")),
99
+ db=kw.get("db"),
100
+ echo=kw.get("echo", False),
101
+ charset=kw.get("charset", "utf8"),
102
+ autocommit=False, # kw.get("autocommit", False),
103
+ maxsize=kw.get("maxsize", 10),
104
+ minsize=kw.get("minsize", 5),
105
+ cursorclass=AttrDictCursor,
106
+ loop=loop,
107
+ )
108
+ info(f"Database connection successfully for mysql/{kw.get('db')}.")
109
+ except Exception as e:
110
+ # print(traceback.format_exc())
111
+ error(f"Database connection failed,the instance : mysql/{kw.get('db')}")
112
+ return self
@@ -0,0 +1,116 @@
1
+ import aiopg
2
+ from cloudoll.logging import error
3
+ from cloudoll.orm.base import MeteBase, QueryTypes
4
+ from cloudoll.logging import info, error
5
+ from typing import Any, Optional
6
+
7
+ class Postgres(MeteBase):
8
+ def __init__(self):
9
+ self.pool: Optional[aiopg.Pool] = None
10
+ self.driver = "postgres"
11
+
12
+ def __call__(self, *args: Any, **kwds: Any) -> Any:
13
+ self.__init__(*args, **kwds)
14
+ return self
15
+
16
+ async def close(self):
17
+ if self.pool:
18
+ self.pool.close()
19
+ await self.pool.wait_closed()
20
+
21
+ async def query(
22
+ self,
23
+ sql,
24
+ params=None,
25
+ query_type: QueryTypes = QueryTypes.COUNT,
26
+ size: int = 10,
27
+ ):
28
+ sql = sql.replace("?", "%s").replace("`", '"')
29
+ if not self.pool:
30
+ raise ValueError("must be create_engine first.")
31
+ if self.pool._closing or self.pool._closed:
32
+ return None
33
+
34
+ async with self.pool.acquire() as conn:
35
+ if conn.echo:
36
+ info("sql: %s ,%s", sql, params)
37
+
38
+ async with conn.cursor() as cursor:
39
+ # current_cursor = getattr(cursor, 'lastrowid', None)
40
+ if (
41
+ query_type == QueryTypes.CREATEBATCH
42
+ or query_type == QueryTypes.UPDATEBATCH
43
+ ):
44
+ await cursor.executemany(sql, params)
45
+ else:
46
+ await cursor.execute(sql, params)
47
+
48
+ # await conn.commit()
49
+ result = None
50
+
51
+ if query_type == QueryTypes.ALL and cursor.description is not None:
52
+ columns = [desc[0] for desc in cursor.description]
53
+ rows = await cursor.fetchall()
54
+ result = [dict(zip(columns, row)) for row in rows]
55
+ return result
56
+ elif query_type == QueryTypes.ONE and cursor.description is not None:
57
+ columns = [desc[0] for desc in cursor.description]
58
+ row = await cursor.fetchone()
59
+ result = dict(zip(columns, row)) if row else {}
60
+ return result
61
+ elif query_type == QueryTypes.MANY and cursor.description is not None:
62
+ columns = [desc[0] for desc in cursor.description]
63
+ rows = await cursor.fetchmany(size)
64
+ result = [dict(zip(columns, row)) for row in rows]
65
+ return result
66
+ elif query_type == QueryTypes.COUNT:
67
+ result = await cursor.fetchone()
68
+ count = 0
69
+ if result is None:
70
+ return count
71
+ for value in result:
72
+ count = value
73
+ return count
74
+ elif query_type == QueryTypes.GROUP_COUNT:
75
+ result = await cursor.fetchall()
76
+ return 0 if not result else len(result)
77
+ elif query_type == QueryTypes.CREATE:
78
+ result = cursor.rowcount > 0
79
+ id = cursor.lastrowid
80
+ return result, id
81
+ elif query_type == QueryTypes.CREATEBATCH:
82
+ count = cursor.rowcount
83
+ id = cursor.lastrowid
84
+ return count, id
85
+ elif query_type == QueryTypes.UPDATE:
86
+ return cursor.rowcount > 0
87
+ elif query_type == QueryTypes.UPDATEBATCH:
88
+ return cursor.rowcount
89
+ elif query_type == QueryTypes.DELETE:
90
+ return cursor.rowcount > 0
91
+
92
+ async def create_engine(self, **kw):
93
+ try:
94
+ host = (kw.get("host", "localhost"),)
95
+ port = (kw.get("port", 5432),)
96
+ user = (kw.get("username"),)
97
+ password = (str(kw.get("password", "")),)
98
+ db = (kw.get("db"),)
99
+ dsn = f"dbname={db[0]} user={user[0]} password={password[0]} host={host[0]} port={port[0]}" # aiopg
100
+ # dsn = f"postgres://{user[0]}:{password[0]}@{host[0]}:{port[0]}/{db[0]}" # asyncpg
101
+ self.pool = await aiopg.create_pool(
102
+ dsn=dsn,
103
+ timeout=float(kw.get("timeout", 60)),
104
+ echo=kw.get("echo", False), # aiopg
105
+ # max_size=kw.get("maxsize", 10), # asyncpg
106
+ # min_size=kw.get("minsize", 5), # asyncpg
107
+ maxsize=kw.get("maxsize", 10), # aiopg
108
+ minsize=kw.get("minsize", 5), # aiopg
109
+ )
110
+ info(f"Database connection successfully for postgres/{kw.get('db')}")
111
+ except Exception as e:
112
+ error(e)
113
+ # print(traceback.format_exc())
114
+ error(f"Database connection failed,the instance : postgres/{kw.get('db')}")
115
+
116
+ return self
@@ -42,7 +42,7 @@ class B(Model):
42
42
 
43
43
  class C(Model):
44
44
 
45
- __table__ = "i_network_speed_result"
45
+ __table__ = "c"
46
46
 
47
47
  id = models.BigIntegerField(primary_key=True, max_length=64, not_null=True)
48
48
  pack_id = models.BigIntegerField(max_length=64, default="0", not_null=True)
@@ -16,7 +16,7 @@ import time
16
16
  from urllib import parse
17
17
  from aiohttp import web, hdrs
18
18
  from aiohttp.web import Response
19
- from aiohttp.web_ws import WebSocketResponse,WSMsgType
19
+ from aiohttp.web_ws import WebSocketResponse, WSMsgType
20
20
  from aiohttp.web_response import StreamResponse
21
21
  from aiohttp.web_request import Request
22
22
  from aiohttp.typedefs import LooseHeaders
@@ -28,8 +28,6 @@ from aiohttp_session import (
28
28
  cookie_storage,
29
29
  )
30
30
  from cloudoll.web.settings import get_config
31
- import aiomcache
32
- from redis import asyncio as aioredis
33
31
  from cloudoll.logging import info
34
32
  from cloudoll.orm.model import Model
35
33
  from cloudoll.web import jwt
@@ -62,6 +60,7 @@ async def _set_session_route(request: Request):
62
60
 
63
61
 
64
62
  def _auto_reg_module(module_dir: str):
63
+ info(f"Auto-registration {module_dir}")
65
64
  base_path = Path(module_dir).resolve()
66
65
  if str(base_path.parent) not in sys.path:
67
66
  sys.path.insert(0, str(base_path.parent))
@@ -129,8 +128,8 @@ async def _render_result(request: Request, func):
129
128
 
130
129
  def _sa_ignore_hash(method, path):
131
130
  md5 = hashlib.md5()
132
- hashstr = f"{method}{path}"
133
- md5.update(hashstr.encode("utf-8"))
131
+ hash_str = f"{method}{path}"
132
+ md5.update(hash_str.encode("utf-8"))
134
133
  return md5.hexdigest()
135
134
 
136
135
 
@@ -140,8 +139,8 @@ def _parse_int(num):
140
139
 
141
140
  def _sa_ignore_middleware():
142
141
  async def set_ignore(ctx, handler):
143
- hashstr = _sa_ignore_hash(ctx.method, ctx.path)
144
- ctx.is_sa_ignore = hashstr in ctx.app.ignore_paths
142
+ hash_str = _sa_ignore_hash(ctx.method, ctx.path)
143
+ ctx.is_sa_ignore = hash_str in ctx.app.ignore_paths
145
144
  start_time = time.time()
146
145
  response = await handler(ctx)
147
146
  end_time = time.time()
@@ -162,13 +161,18 @@ class Application(object):
162
161
  self.config = {}
163
162
  self.clean_up = False
164
163
 
165
- def _load_life_cycle(self, entry_model=None):
164
+ def _load_life_cycle(self, entry_model=None, func_name=None):
166
165
  try:
167
166
  if not entry_model:
168
167
  return
169
168
 
170
169
  entry = importlib.import_module(entry_model, ".")
171
170
 
171
+ if func_name:
172
+ func = getattr(entry, func_name)
173
+ func(self)
174
+ return
175
+
172
176
  life_cycle = ["on_startup", "on_shutdown", "on_cleanup", "on_task"]
173
177
  for cycle in life_cycle:
174
178
  if hasattr(entry, cycle):
@@ -199,15 +203,17 @@ class Application(object):
199
203
  config = get_config(env or "local")
200
204
  self.config = config
201
205
 
206
+ # try to load func and override configuration
207
+ self._load_life_cycle(entry_model, func_name="on_create")
208
+
202
209
  sa_ignore_mid = _sa_ignore_middleware()
203
210
  sa_ignore_mid.__middleware_version__ = 1
204
211
  self._middleware.append(sa_ignore_mid)
205
212
 
206
213
  # middlewares
207
214
  _auto_reg_module("middlewares")
208
- info("Auto-registration middleware")
209
215
 
210
- conf_server = config.get("server", {})
216
+ conf_server = self.config.get("server", {})
211
217
  client_max_size = 1024**2 * 2
212
218
  if conf_server is not None:
213
219
  client_max_size = conf_server.get("client_max_size", client_max_size)
@@ -218,12 +224,16 @@ class Application(object):
218
224
  client_max_size=_parse_int(client_max_size),
219
225
  )
220
226
 
227
+ # load life
228
+ # entry = conf_server.get("entry", entry_model)
229
+ # self._load_life_cycle(entry)
230
+
221
231
  # database
222
232
  self.app.ignore_paths = set()
223
233
  self.app.db = Object()
224
234
  self.app.on_startup.append(self._init_database)
225
235
  self.app.on_cleanup.append(self._close_database)
226
- self.app.config = config
236
+ self.app.config = self.config
227
237
  self.app.env = env
228
238
  self.app.jwt_encode = self.jwt_encode
229
239
  self.app.jwt_decode = self.jwt_decode
@@ -231,14 +241,9 @@ class Application(object):
231
241
  self.app.on_startup.append(self._init_session)
232
242
  # router:
233
243
  _auto_reg_module("controllers")
234
- info("Auto-registration controller")
235
244
 
236
245
  self.app.add_routes(self._route_table)
237
246
 
238
- # load life
239
- entry = conf_server.get("entry", entry_model)
240
- self._load_life_cycle(entry)
241
-
242
247
  # static
243
248
  if conf_server is not None:
244
249
  conf_st = conf_server.get("static", {})
@@ -283,7 +288,7 @@ class Application(object):
283
288
  if conf_db:
284
289
  # for db_key in conf_db:
285
290
  # apps.db[db_key] = await create_engine(**conf_db[db_key])
286
-
291
+
287
292
  tasks = [create_engine(**conf_db[db_key]) for db_key in conf_db]
288
293
  engines = await asyncio.gather(*tasks)
289
294
  for db_key, engine in zip(conf_db.keys(), engines):
@@ -309,6 +314,8 @@ class Application(object):
309
314
  cfg, qs = parse_coon(redis_url)
310
315
  redis_url = f"{cfg['type']}://{cfg['username']}:{cfg['password']}@{cfg['host']}:{cfg['port']}/{cfg['db']}"
311
316
 
317
+ from redis import asyncio as aioredis
318
+
312
319
  redis = await aioredis.from_url(redis_url, **qs)
313
320
  apps.redis = redis
314
321
  storage = redis_storage.RedisStorage(
@@ -324,6 +331,8 @@ class Application(object):
324
331
  host = mcache_conf.get("host")
325
332
  port = mcache_conf.get("port", 11211)
326
333
 
334
+ import aiomcache
335
+
327
336
  mc = aiomcache.Client(host, port)
328
337
  apps.memcached = mc
329
338
  storage = memcached_storage.MemcachedStorage(
@@ -382,12 +391,14 @@ class Application(object):
382
391
  def add_router(self, path, method, name, sa_ignore):
383
392
  def inner(handler):
384
393
  handler = RequestHandler(handler)
385
- self.router.add_route(method, path, handler, name=name)
394
+ if self.router is not None:
395
+ self.router.add_route(method, path, handler, name=name)
386
396
  return handler
387
397
 
388
398
  if sa_ignore:
389
- hashstr = _sa_ignore_hash(method, path)
390
- self.app.ignore_paths.add(hashstr)
399
+ if self.app is not None:
400
+ hash_str = _sa_ignore_hash(method, path)
401
+ self.app.ignore_paths.add(hash_str)
391
402
  return inner
392
403
 
393
404
  def add_middleware(self, func):
@@ -414,27 +425,39 @@ class Application(object):
414
425
 
415
426
  @property
416
427
  def router(self):
417
- return self.app.router
428
+ if self.app is not None:
429
+ return self.app.router
430
+ return None
418
431
 
419
432
  @property
420
433
  def middlewares(self):
421
- return self.app.middlewares
434
+ if self.app is not None:
435
+ return self.app.middlewares
436
+ return None
422
437
 
423
438
  @property
424
439
  def on_startup(self):
425
- return self.app.on_startup
440
+ if self.app is not None:
441
+ return self.app.on_startup
442
+ return None
426
443
 
427
444
  @property
428
445
  def on_shutdown(self):
429
- return self.app.on_shutdown
446
+ if self.app is not None:
447
+ return self.app.on_shutdown
448
+ return None
430
449
 
431
450
  @property
432
451
  def on_cleanup(self):
433
- return self.app.on_cleanup
452
+ if self.app is not None:
453
+ return self.app.on_cleanup
454
+ return None
434
455
 
435
456
  @property
436
457
  def on_task(self):
437
- return self.app.cleanup_ctx
458
+ if self.app is not None:
459
+ return self.app.cleanup_ctx
460
+ return None
438
461
 
439
462
 
440
463
  class View(web.View):
@@ -525,8 +548,8 @@ def delete(path: str, name=None, sa_ignore=False):
525
548
  def routes(path: str, sa_ignore=False):
526
549
  if sa_ignore:
527
550
  for method in hdrs.METH_ALL:
528
- hashstr = _sa_ignore_hash(method, path)
529
- app.app.ignore_paths.add(hashstr)
551
+ hash_str = _sa_ignore_hash(method, path)
552
+ app.app.ignore_paths.add(hash_str)
530
553
  return app.route_table.view(path)
531
554
 
532
555
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudoll
3
- Version: 3.0.6
3
+ Version: 3.0.7
4
4
  Summary: Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use.
5
5
  Home-page: https://github.com/smallerqiu/cloudoll-py
6
6
  Author: Qiu
@@ -22,6 +22,8 @@ cloudoll/logging/__init__.py
22
22
  cloudoll/mail/__init__.py
23
23
  cloudoll/mail/smtp.py
24
24
  cloudoll/orm/__init__.py
25
+ cloudoll/orm/awsmysql.py
26
+ cloudoll/orm/awspostgres.py
25
27
  cloudoll/orm/base.py
26
28
  cloudoll/orm/err.py
27
29
  cloudoll/orm/field.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cloudoll"
7
- version = "3.0.6"
7
+ version = "3.0.7"
8
8
  description = "Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use."
9
9
  authors = [
10
10
  {name = "Qiu", email = "smallerqiu@gmail.com"},
@@ -1 +0,0 @@
1
- __version__ = "3.0.6"
@@ -1,247 +0,0 @@
1
- from redis import asyncio as aioredis
2
- from cloudoll.orm.parse import parse_coon
3
- from cloudoll.orm.base import MeteBase, QueryTypes
4
- from typing import Any
5
- from cloudoll.logging import info, error
6
- import traceback
7
- import aiomysql
8
- from aiomysql import Pool as MYPool
9
-
10
- import aiopg as pg
11
- from aiopg.pool import Pool as PGPool
12
- from typing import Optional
13
-
14
- __all__ = ["create_engine"]
15
-
16
-
17
- async def create_engine(**kw):
18
- url = kw.get("url")
19
- driver = None
20
- configs = {}
21
- query = {}
22
-
23
- if url is not None:
24
- configs, query = parse_coon(url)
25
- driver = configs["type"]
26
- else:
27
- driver = kw.get("type")
28
- configs = kw
29
-
30
- # info("DB Config:", configs, query)
31
-
32
- if driver == "mysql":
33
- return await Mysql().create_engine(**configs, **query)
34
- elif driver == "postgres" or driver == "postgressql":
35
- return await Postgres().create_engine(**configs, **query)
36
- elif driver == "redis" or driver == "rediss":
37
- """
38
- redis://[[username]:[password]]@localhost:6379/0
39
- rediss://[[username]:[password]]@localhost:6379/0
40
- """
41
- if url is None:
42
- url = f"{driver}://{configs['username']}:{configs['password']}@{configs['host']}:{configs['port']}/{configs['db']}"
43
- return await aioredis.from_url(url, **query)
44
- else:
45
- raise ValueError("Not support this database type.")
46
-
47
-
48
- class Postgres(MeteBase):
49
- def __init__(self, pool=None):
50
- # self.pool: Optional[PGPool] = pool
51
- self.driver = "postgres"
52
-
53
- def __call__(self, *args: Any, **kwds: Any) -> Any:
54
- self.__init__(*args, **kwds)
55
-
56
- async def query(self, sql, params=None, query_type: QueryTypes = QueryTypes.COUNT, size: int = 10):
57
- sql = sql.replace("?", "%s").replace("`", '"')
58
- if not self.pool:
59
- raise ValueError("must be create_engine first.")
60
- if self.pool._closing or self.pool._closed:
61
- return None
62
-
63
- async with self.pool.acquire() as conn:
64
- if conn.echo:
65
- info("sql: %s ,%s", sql, params)
66
-
67
- async with conn.cursor() as cursor:
68
- # current_cursor = getattr(cursor, 'lastrowid', None)
69
- if (
70
- query_type == QueryTypes.CREATEBATCH
71
- or query_type == QueryTypes.UPDATEBATCH
72
- ):
73
- # aiopg don't support executemany
74
- raise RuntimeError("postgres don't support executemany")
75
- else:
76
- await cursor.execute(sql, params)
77
-
78
- result = None
79
-
80
- if query_type == QueryTypes.ALL and cursor.description is not None:
81
- columns = [desc[0] for desc in cursor.description]
82
- rows = await cursor.fetchall()
83
- result = [dict(zip(columns, row)) for row in rows]
84
- return result
85
- elif query_type == QueryTypes.ONE and cursor.description is not None:
86
- columns = [desc[0] for desc in cursor.description]
87
- row = await cursor.fetchone()
88
- result = dict(zip(columns, row)) if row else {}
89
- return result
90
- elif query_type == QueryTypes.MANY and cursor.description is not None:
91
- columns = [desc[0] for desc in cursor.description]
92
- rows = await cursor.fetchmany(size)
93
- result = [dict(zip(columns, row)) for row in rows]
94
- return result
95
- elif query_type == QueryTypes.COUNT:
96
- result = await cursor.fetchone()
97
- count = 0
98
- if result is None:
99
- return count
100
- for value in result:
101
- count = value
102
- return count
103
- elif query_type == QueryTypes.GROUP_COUNT:
104
- result = await cursor.fetchall()
105
- return 0 if not result else len(result)
106
- elif query_type == QueryTypes.CREATE:
107
- result = cursor.rowcount > 0
108
- id = cursor.lastrowid
109
- return result, id
110
- elif query_type == QueryTypes.CREATEBATCH:
111
- count = cursor.rowcount
112
- id = cursor.lastrowid
113
- return count, id
114
- elif query_type == QueryTypes.UPDATE:
115
- return cursor.rowcount > 0
116
- elif query_type == QueryTypes.UPDATEBATCH:
117
- return cursor.rowcount
118
- elif query_type == QueryTypes.DELETE:
119
- return cursor.rowcount > 0
120
-
121
- async def create_engine(self, **kw):
122
- try:
123
- host = (kw.get("host", "localhost"),)
124
- port = (kw.get("port", 5432),)
125
- user = (kw.get("username"),)
126
- password = (str(kw.get("password", "")),)
127
- db = (kw.get("db"),)
128
- dsn = f"dbname={db[0]} user={user[0]} password={password[0]} host={host[0]} port={port[0]}" # aiopg
129
- # dsn = f"postgres://{user[0]}:{password[0]}@{host[0]}:{port[0]}/{db[0]}" # asyncpg
130
- self.pool = await pg.create_pool(
131
- dsn=dsn,
132
- timeout=float(kw.get("timeout", 60)),
133
- echo=kw.get("echo", False), # aiopg
134
- # max_size=kw.get("maxsize", 10), # asyncpg
135
- # min_size=kw.get("minsize", 5), # asyncpg
136
- maxsize=kw.get("maxsize", 10), # aiopg
137
- minsize=kw.get("minsize", 5), # aiopg
138
- )
139
- info(f"Database connection successfuly for postgres/{kw.get('db')}")
140
- except Exception as e:
141
- error(e)
142
- # print(traceback.format_exc())
143
- error(f"Database connection failed,the instance : postgres/{kw.get('db')}")
144
-
145
- return self
146
-
147
-
148
- class AttrDict(dict):
149
- """Dict that can get attribute by dot, and doesn't raise KeyError"""
150
-
151
- def __getattr__(self, name):
152
- try:
153
- return self[name]
154
- except KeyError:
155
- return None
156
-
157
-
158
- class AttrDictCursor(aiomysql.DictCursor):
159
- dict_type = AttrDict
160
-
161
-
162
- class Mysql(MeteBase):
163
- def __init__(self, pool=None):
164
- # self.pool: Optional[MYPool] = pool
165
- self.driver = "mysql"
166
-
167
- def __call__(self, *args: Any, **kwds: Any) -> Any:
168
- self.__init__(*args, **kwds)
169
- return self
170
-
171
- async def query(self, sql, params=None, query_type: QueryTypes = QueryTypes.ONE, size: int = 10):
172
- sql = sql.replace("?", "%s")
173
- if not self.pool:
174
- raise ValueError("must be create_engine first.")
175
- if self.pool._closing or self.pool._closed:
176
- return None
177
- async with self.pool.acquire() as conn:
178
- if conn.echo:
179
- info("sql: %s , %s", sql, params)
180
-
181
- async with conn.cursor() as cursor:
182
- # current_cursor = getattr(cursor, 'lastrowid', None)
183
- if (
184
- query_type == QueryTypes.CREATEBATCH
185
- or query_type == QueryTypes.UPDATEBATCH
186
- ):
187
- await cursor.executemany(sql, params)
188
- else:
189
- await cursor.execute(sql, params)
190
-
191
- await conn.commit()
192
-
193
- if query_type == QueryTypes.ALL:
194
- return await cursor.fetchall()
195
- elif query_type == QueryTypes.ONE:
196
- return await cursor.fetchone()
197
- elif query_type == QueryTypes.MANY:
198
- return await cursor.fetchmany(size)
199
- elif query_type == QueryTypes.COUNT:
200
- rows = await cursor.fetchone()
201
- count = 0
202
- if rows is None:
203
- return count
204
- for row in rows:
205
- count = rows[row]
206
- return count
207
- elif query_type == QueryTypes.GROUP_COUNT:
208
- result = await cursor.fetchall()
209
- return 0 if not result else len(result)
210
- elif query_type == QueryTypes.CREATE:
211
- result = cursor.rowcount > 0
212
- id = cursor.lastrowid
213
- return result, id
214
- elif query_type == QueryTypes.CREATEBATCH:
215
- count = cursor.rowcount
216
- id = cursor.lastrowid
217
- return count, id
218
- elif query_type == QueryTypes.UPDATE:
219
- return cursor.rowcount > 0
220
- elif query_type == QueryTypes.UPDATEBATCH:
221
- return cursor.rowcount
222
- elif query_type == QueryTypes.DELETE:
223
- return cursor.rowcount > 0
224
-
225
- self.pool.release(conn)
226
-
227
- async def create_engine(self, loop=None, **kw):
228
- try:
229
- self.pool = await aiomysql.create_pool(
230
- host=kw.get("host", "localhost"),
231
- port=kw.get("port", 3306),
232
- user=kw.get("username"),
233
- password=str(kw.get("password", "")),
234
- db=kw.get("db"),
235
- echo=kw.get("echo", False),
236
- charset=kw.get("charset", "utf8"),
237
- autocommit=False, # kw.get("autocommit", False),
238
- maxsize=kw.get("maxsize", 10),
239
- minsize=kw.get("minsize", 5),
240
- cursorclass=AttrDictCursor,
241
- loop=loop,
242
- )
243
- info(f"Database connection successfuly for mysql/{kw.get('db')}.")
244
- except Exception as e:
245
- # print(traceback.format_exc())
246
- error(f"Database connection failed,the instance : mysql/{kw.get('db')}")
247
- return self
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- from cloudoll.orm import Mysql
5
-
6
- # for config folder conf.{env}.yaml
7
-
8
- database:
9
- mysql:
10
- type: mysql # important ,default mysql
11
- host: 127.0.0.1
12
- port: 3306
13
- user: root
14
- password: 123456
15
- db: test
16
- charset:utf8mb4
17
- pool_size:5
18
-
19
- # to get yaml config
20
- config = ....(database.mysql)
21
-
22
- pool = await Mysql().create_engine(**config)
23
- result = await pool.query("sql")
24
- """
25
- __author__ = "Qiu / smallerqiu@gmail.com"
26
-
27
- from aiomysql import create_pool, DictCursor
28
-
29
- # from aiomysql.cursors import Cursor
30
- # from aiomysql.connection import Connection
31
- from cloudoll.logging import error
32
-
33
- # from inspect import isclass, isfunction
34
- from cloudoll.orm.base import MeteBase
35
-
36
-
37
- class AttrDict(dict):
38
- """Dict that can get attribute by dot, and doesn't raise KeyError"""
39
-
40
- def __getattr__(self, name):
41
- try:
42
- return self[name]
43
- except KeyError:
44
- return None
45
-
46
-
47
- class AttrDictCursor(DictCursor):
48
- dict_type = AttrDict
49
-
50
-
51
- class Mysql(MeteBase):
52
- # def __init__(self):
53
- # self.pool: Optional[Pool] = None
54
- # self.cursor: Cursor = None
55
- # self.conn: Connection = None
56
- # self.__MODELS__ = []
57
-
58
- # def __call__(cls, *args: Any, **kwds: Any) -> Any:
59
- # cls.__init__(*args, **kwds)
60
- # return cls()
61
-
62
- # @classmethod
63
- async def create_engine(self, loop=None, **kw):
64
- try:
65
- self.pool = await create_pool(
66
- host=kw.get("host", "localhost"),
67
- port=kw.get("port", 3306),
68
- user=kw.get("user"),
69
- password=str(kw.get("password", "")),
70
- db=kw.get("db"),
71
- echo=kw.get("echo", False),
72
- charset=kw.get("charset", "utf8"),
73
- autocommit=False, # kw.get("autocommit", False),
74
- maxsize=kw.get("maxsize", 10),
75
- minsize=kw.get("pool_size", 5),
76
- cursorclass=AttrDictCursor,
77
- connect_timeout=kw.get("connect_timeout", 10),
78
- loop=loop,
79
- )
80
- except Exception as e:
81
- error(f"Database connection failed,the instance : {kw.get('db')}")
82
- return self
@@ -1,68 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- from cloudoll.orm.postgres import Postgres
5
-
6
- # for config folder conf.{env}.yaml
7
-
8
- database:
9
- pg:
10
- type: postgres # important ,default mysql
11
- host: 127.0.0.1
12
- port: 3306
13
- user: root
14
- password: 123456
15
- db: test
16
- echo: True
17
- timeout: 60
18
- pool_size:5
19
-
20
- # to get yaml config
21
- config = ....(database.postgres)
22
-
23
- pool = await Postgres().create_engine(**config)
24
- result = await pool.query("sql")
25
- """
26
- __author__ = "Qiu / smallerqiu@gmail.com"
27
-
28
- from aiopg import create_pool
29
- from cloudoll.logging import error
30
- from cloudoll.orm.base import MeteBase
31
-
32
-
33
- class Postgres(MeteBase):
34
- # def __init__(self):
35
- # self.pool: Optional[Pool] = None
36
- # self.cursor: Optional[Cursor] = None
37
- # self.conn: Optional[Connection] = None
38
- # self.__MODELS__ = []
39
-
40
- # def __call__(cls, *args: Any, **kwds: Any) -> Any:
41
- # cls.__init__(*args, **kwds)
42
- # return cls()
43
-
44
- @classmethod
45
- async def create_engine(cls, **kw):
46
- try:
47
- host = (kw.get("host", "localhost"),)
48
- port = (kw.get("port", 5432),)
49
- user = (kw.get("user"),)
50
- password = (str(kw.get("password", "")),)
51
- db = (kw.get("db"),)
52
- dsn = f"dbname={db[0]} user={user[0]} password={password[0]} host={host[0]} port={port[0]}"
53
- cls.pool = await create_pool(
54
- dsn=dsn,
55
- timeout=kw.get("timeout", 10.0),
56
- enable_json=kw.get("enable_json", False),
57
- enable_hstore=kw.get("enable_hstore", False),
58
- enable_uuid=kw.get("enable_uuid", False),
59
- pool_recycle=kw.get("pool_recycle", 10),
60
- echo=kw.get("echo", False),
61
- minsize=kw.get("pool_size", 5),
62
- maxsize=kw.get("pool_size", 10),
63
- )
64
- except Exception as e:
65
- # error(e)
66
- error(f"Database connection failed,the instance : {kw.get('db')}")
67
-
68
- return cls
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes