codosdk 1.0.50__tar.gz → 1.0.51__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.
- {codosdk-1.0.50 → codosdk-1.0.51}/PKG-INFO +1 -1
- {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/PKG-INFO +1 -1
- {codosdk-1.0.50 → codosdk-1.0.51}/setup.py +1 -1
- codosdk-1.0.51/websdk2/db_context.py +157 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/mqhelper.py +1 -1
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/pydantic_utils.py +7 -2
- codosdk-1.0.50/websdk2/db_context.py +0 -150
- {codosdk-1.0.50 → codosdk-1.0.51}/LICENSE +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/README.md +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/SOURCES.txt +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/dependency_links.txt +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/requires.txt +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/top_level.txt +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/opssdk/__init__.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/opssdk/utils/__init__.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/pyproject.toml +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/setup.cfg +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/__init__.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/api_set.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/__init__.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/admin_apis.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/agent_apis.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/cmdb_apis.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/kerrigan_apis.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/mgv4_apis.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/notice_apis.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/task_apis.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/application.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/base_handler.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cache.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cache_context.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/client.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud/__init__.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud/qcloud_api.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud/ucloud_api.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud_utils.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/configs.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/consts.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/crud_utils.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/error.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/fetch_coroutine.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/jwt_token.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/ldap.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/logger.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/model_utils.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/program.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/salt_api.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/sqlalchemy_pagination.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/tools.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/__init__.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/cc_crypto.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/date_format.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/pydantic_utils_v2.py +0 -0
- {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/web_logs.py +0 -0
|
@@ -9,7 +9,7 @@ desc : CODO SDK
|
|
|
9
9
|
import sys
|
|
10
10
|
from setuptools import setup, find_packages
|
|
11
11
|
|
|
12
|
-
VERSION = '1.0.
|
|
12
|
+
VERSION = '1.0.51'
|
|
13
13
|
|
|
14
14
|
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 6):
|
|
15
15
|
print('This program requires at least Python 2.7 or 3.6 to run.')
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Author : shenshuo
|
|
5
|
+
date : 2017年10月17日17:23:19
|
|
6
|
+
role : 数据库连接
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import pymysql
|
|
10
|
+
from urllib.parse import quote_plus
|
|
11
|
+
from sqlalchemy import create_engine
|
|
12
|
+
from sqlalchemy.pool import NullPool
|
|
13
|
+
from sqlalchemy.orm import sessionmaker
|
|
14
|
+
from .consts import const
|
|
15
|
+
from .configs import configs
|
|
16
|
+
|
|
17
|
+
engines = {}
|
|
18
|
+
scheduler_engines = {}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DBConfigError(Exception):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# 调度器专用引擎池
|
|
26
|
+
|
|
27
|
+
def init_scheduler_engine(**settings):
|
|
28
|
+
databases = settings.get(const.DB_CONFIG_ITEM) or configs[const.DB_CONFIG_ITEM]
|
|
29
|
+
|
|
30
|
+
for dbkey, db_conf in databases.items():
|
|
31
|
+
# 获取配置
|
|
32
|
+
dbuser = db_conf.get(const.DBUSER_KEY)
|
|
33
|
+
dbpwd = db_conf.get(const.DBPWD_KEY)
|
|
34
|
+
dbhost = db_conf.get(const.DBHOST_KEY)
|
|
35
|
+
dbport = db_conf.get(const.DBPORT_KEY)
|
|
36
|
+
dbname = db_conf.get(const.DBNAME_KEY)
|
|
37
|
+
|
|
38
|
+
# 验证配置完整性
|
|
39
|
+
if None in (dbuser, dbpwd, dbhost, dbname):
|
|
40
|
+
raise DBConfigError(f"Incomplete database configuration for '{dbkey}'")
|
|
41
|
+
|
|
42
|
+
# 创建调度器专用引擎(小规格连接池)
|
|
43
|
+
engine = create_engine(
|
|
44
|
+
f'mysql+pymysql://{dbuser}:{quote_plus(dbpwd)}@{dbhost}:{dbport}/{dbname}?charset=utf8mb4',
|
|
45
|
+
logging_name=dbkey,
|
|
46
|
+
poolclass=None, # QueuePool
|
|
47
|
+
pool_size=10, # 10个常驻连接(调度器用)
|
|
48
|
+
max_overflow=30, # 30个溢出连接
|
|
49
|
+
pool_recycle=1800, # 30分钟回收
|
|
50
|
+
pool_pre_ping=True, # 启用连接检查
|
|
51
|
+
pool_timeout=10, # 5秒超时
|
|
52
|
+
echo_pool=False # 关闭连接池日志
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
scheduler_engines[dbkey] = engine
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def get_scheduler_engine(dbkey='default', **settings):
|
|
59
|
+
if not scheduler_engines:
|
|
60
|
+
init_scheduler_engine(**settings)
|
|
61
|
+
return scheduler_engines[dbkey]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _build_db_url(db_conf, const) -> str:
|
|
65
|
+
"""构建数据库连接URL"""
|
|
66
|
+
return 'mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'.format(
|
|
67
|
+
user=db_conf[const.DBUSER_KEY],
|
|
68
|
+
pwd=quote_plus(db_conf[const.DBPWD_KEY]),
|
|
69
|
+
host=db_conf[const.DBHOST_KEY],
|
|
70
|
+
port=db_conf[const.DBPORT_KEY],
|
|
71
|
+
dbname=db_conf[const.DBNAME_KEY]
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def init_engine(use_pool=False, pool_config=None, **settings):
|
|
76
|
+
databases = settings.get(const.DB_CONFIG_ITEM) or configs[const.DB_CONFIG_ITEM]
|
|
77
|
+
|
|
78
|
+
# 默认连接池配置 - 优化后的推荐值
|
|
79
|
+
default_pool_config = {
|
|
80
|
+
'pool_size': 20, # 常驻连接: 20 (原10)
|
|
81
|
+
'max_overflow': 30, # 溢出连接: 30 (原50, 过大)
|
|
82
|
+
'pool_recycle': 3600, # 回收时间: 1小时
|
|
83
|
+
'pool_pre_ping': True, # 预检查: 启用 (避免僵尸连接)
|
|
84
|
+
'pool_timeout': 20, # 获取超时: 20秒 (原60秒, 过长)
|
|
85
|
+
'echo_pool': False, # 连接池日志: 关闭 (生产环境)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# 合并用户自定义配置
|
|
89
|
+
if pool_config:
|
|
90
|
+
default_pool_config.update(pool_config)
|
|
91
|
+
|
|
92
|
+
for dbkey, db_conf in databases.items():
|
|
93
|
+
db_url = _build_db_url(db_conf, const)
|
|
94
|
+
|
|
95
|
+
if use_pool:
|
|
96
|
+
# 使用连接池配置
|
|
97
|
+
engine = create_engine(
|
|
98
|
+
db_url,
|
|
99
|
+
logging_name=dbkey,
|
|
100
|
+
poolclass=None, # 默认 QueuePool
|
|
101
|
+
**default_pool_config
|
|
102
|
+
)
|
|
103
|
+
else:
|
|
104
|
+
# 不使用连接池 (每次新建连接)
|
|
105
|
+
engine = create_engine(db_url, logging_name=dbkey, poolclass=NullPool)
|
|
106
|
+
|
|
107
|
+
engines[dbkey] = engine
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def get_db_url(dbkey):
|
|
111
|
+
"""获取数据库连接URL"""
|
|
112
|
+
db_conf = configs[const.DB_CONFIG_ITEM][dbkey]
|
|
113
|
+
return _build_db_url(db_conf, const)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class DBContext:
|
|
117
|
+
def __init__(self, rw='r', db_key=None, need_commit=False, use_pool=False, pool_config=None, **settings):
|
|
118
|
+
self.__db_key = db_key or (const.DEFAULT_DB_KEY if rw == 'w' else const.READONLY_DB_KEY)
|
|
119
|
+
self.__engine = self.__get_db_engine(self.__db_key, use_pool, pool_config, **settings)
|
|
120
|
+
self.need_commit = need_commit
|
|
121
|
+
self.__session = None
|
|
122
|
+
|
|
123
|
+
@staticmethod
|
|
124
|
+
def __get_db_engine(db_key, use_pool, pool_config, **settings):
|
|
125
|
+
"""获取数据库引擎"""
|
|
126
|
+
if not engines:
|
|
127
|
+
init_engine(use_pool=use_pool, pool_config=pool_config, **settings)
|
|
128
|
+
return engines[db_key]
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def session(self):
|
|
132
|
+
"""获取session"""
|
|
133
|
+
return self.__session
|
|
134
|
+
|
|
135
|
+
def __enter__(self):
|
|
136
|
+
"""进入上下文"""
|
|
137
|
+
self.__session = sessionmaker(bind=self.__engine)()
|
|
138
|
+
return self.__session
|
|
139
|
+
|
|
140
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
141
|
+
"""退出上下文"""
|
|
142
|
+
if self.need_commit:
|
|
143
|
+
if exc_type:
|
|
144
|
+
self.__session.rollback()
|
|
145
|
+
else:
|
|
146
|
+
self.__session.commit()
|
|
147
|
+
self.__session.close()
|
|
148
|
+
|
|
149
|
+
def get_session(self):
|
|
150
|
+
"""获取session(向后兼容)"""
|
|
151
|
+
return self.__session
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# ==================== 向后兼容 ====================
|
|
155
|
+
|
|
156
|
+
# DBContextV2 别名(完全兼容旧代码)
|
|
157
|
+
DBContextV2 = DBContext
|
|
@@ -621,4 +621,4 @@ if __name__ == "__main__":
|
|
|
621
621
|
# 示例3:向后兼容的使用方式
|
|
622
622
|
print("=== 向后兼容使用 ===")
|
|
623
623
|
with MessageQueueBase('test_exchange', 'direct', routing_key='test.key', queue_name='task_test_queue') as old_mq:
|
|
624
|
-
old_mq.publish_message("Hello from old interface!")
|
|
624
|
+
old_mq.publish_message("Hello from old interface!")
|
|
@@ -15,16 +15,21 @@ from sqlalchemy.inspection import inspect
|
|
|
15
15
|
from sqlalchemy.orm.properties import ColumnProperty
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# 删除的时候一般只有id
|
|
19
19
|
class PydanticDel(BaseModel):
|
|
20
20
|
id: int
|
|
21
21
|
|
|
22
|
+
|
|
22
23
|
class PydanticDelList(BaseModel):
|
|
23
24
|
id_list: list[int]
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class OrmConfig(BaseConfig):
|
|
27
|
-
|
|
28
|
+
# Pydantic V1/V2 自动兼容, TODO 后续移除V1兼容
|
|
29
|
+
try:
|
|
30
|
+
from_attributes = True # Pydantic V2
|
|
31
|
+
except Exception:
|
|
32
|
+
orm_mode = True # Pydantic V1
|
|
28
33
|
|
|
29
34
|
|
|
30
35
|
def sqlalchemy_to_pydantic(db_model: Type, *, config: Type = OrmConfig, exclude: Container[str] = []) -> Type[
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
# -*-coding:utf-8-*-
|
|
2
|
-
"""
|
|
3
|
-
Author : shenshuo
|
|
4
|
-
date : 2017年10月17日17:23:19
|
|
5
|
-
role : 数据库连接
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import pymysql
|
|
9
|
-
from urllib.parse import quote_plus
|
|
10
|
-
from sqlalchemy import create_engine
|
|
11
|
-
from sqlalchemy.pool import NullPool
|
|
12
|
-
from sqlalchemy.orm import sessionmaker
|
|
13
|
-
from .consts import const
|
|
14
|
-
from .configs import configs
|
|
15
|
-
|
|
16
|
-
engines = {}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def init_engine(**settings):
|
|
20
|
-
if settings:
|
|
21
|
-
databases = settings[const.DB_CONFIG_ITEM]
|
|
22
|
-
else:
|
|
23
|
-
databases = configs[const.DB_CONFIG_ITEM]
|
|
24
|
-
for dbkey, db_conf in databases.items():
|
|
25
|
-
dbuser = db_conf[const.DBUSER_KEY]
|
|
26
|
-
dbpwd = db_conf[const.DBPWD_KEY]
|
|
27
|
-
dbhost = db_conf[const.DBHOST_KEY]
|
|
28
|
-
dbport = db_conf[const.DBPORT_KEY]
|
|
29
|
-
dbname = db_conf[const.DBNAME_KEY]
|
|
30
|
-
engine = create_engine('mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'
|
|
31
|
-
.format(user=dbuser, pwd=quote_plus(dbpwd), host=dbhost, port=dbport, dbname=dbname),
|
|
32
|
-
# logging_name=dbkey)
|
|
33
|
-
logging_name=dbkey, poolclass=NullPool)
|
|
34
|
-
engines[dbkey] = engine
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def get_db_url(dbkey):
|
|
38
|
-
databases = configs[const.DB_CONFIG_ITEM]
|
|
39
|
-
db_conf = databases[dbkey]
|
|
40
|
-
dbuser = db_conf['user']
|
|
41
|
-
dbpwd = db_conf['pwd']
|
|
42
|
-
dbhost = db_conf['host']
|
|
43
|
-
dbport = db_conf.get('port', 3306)
|
|
44
|
-
dbname = db_conf['name']
|
|
45
|
-
|
|
46
|
-
return 'mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'.format(user=dbuser, pwd=quote_plus(dbpwd),
|
|
47
|
-
host=dbhost, port=dbport,
|
|
48
|
-
dbname=dbname, poolclass=NullPool)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class DBContext(object):
|
|
52
|
-
def __init__(self, rw='r', db_key=None, need_commit=False, **settings):
|
|
53
|
-
self.__db_key = db_key
|
|
54
|
-
if not self.__db_key:
|
|
55
|
-
if rw == 'w':
|
|
56
|
-
self.__db_key = const.DEFAULT_DB_KEY
|
|
57
|
-
elif rw == 'r':
|
|
58
|
-
self.__db_key = const.READONLY_DB_KEY
|
|
59
|
-
engine = self.__get_db_engine(self.__db_key, **settings)
|
|
60
|
-
self.__engine = engine
|
|
61
|
-
self.need_commit = need_commit
|
|
62
|
-
|
|
63
|
-
# @property
|
|
64
|
-
# def db_key(self):
|
|
65
|
-
# return self.__db_key
|
|
66
|
-
|
|
67
|
-
@staticmethod
|
|
68
|
-
def __get_db_engine(db_key, **settings):
|
|
69
|
-
if len(engines) == 0:
|
|
70
|
-
init_engine(**settings)
|
|
71
|
-
return engines[db_key]
|
|
72
|
-
|
|
73
|
-
@property
|
|
74
|
-
def session(self):
|
|
75
|
-
return self.__session
|
|
76
|
-
|
|
77
|
-
def __enter__(self):
|
|
78
|
-
self.__session = sessionmaker(bind=self.__engine)()
|
|
79
|
-
return self.__session
|
|
80
|
-
|
|
81
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
82
|
-
if self.need_commit:
|
|
83
|
-
if exc_type:
|
|
84
|
-
self.__session.rollback()
|
|
85
|
-
else:
|
|
86
|
-
self.__session.commit()
|
|
87
|
-
self.__session.close()
|
|
88
|
-
|
|
89
|
-
def get_session(self):
|
|
90
|
-
return self.__session
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def init_engine_v2(**settings):
|
|
94
|
-
if settings:
|
|
95
|
-
databases = settings[const.DB_CONFIG_ITEM]
|
|
96
|
-
else:
|
|
97
|
-
databases = configs[const.DB_CONFIG_ITEM]
|
|
98
|
-
for dbkey, db_conf in databases.items():
|
|
99
|
-
dbuser = db_conf[const.DBUSER_KEY]
|
|
100
|
-
dbpwd = db_conf[const.DBPWD_KEY]
|
|
101
|
-
dbhost = db_conf[const.DBHOST_KEY]
|
|
102
|
-
dbport = db_conf[const.DBPORT_KEY]
|
|
103
|
-
dbname = db_conf[const.DBNAME_KEY]
|
|
104
|
-
engine = create_engine('mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'
|
|
105
|
-
.format(user=dbuser, pwd=quote_plus(dbpwd), host=dbhost, port=dbport, dbname=dbname),
|
|
106
|
-
logging_name=dbkey, poolclass=None, pool_size=10, max_overflow=50, pool_recycle=3600,
|
|
107
|
-
pool_pre_ping=True, pool_timeout=60)
|
|
108
|
-
engines[dbkey] = engine
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
class DBContextV2(object):
|
|
112
|
-
def __init__(self, rw='r', db_key=None, need_commit=False, **settings):
|
|
113
|
-
self.__db_key = db_key
|
|
114
|
-
if not self.__db_key:
|
|
115
|
-
if rw == 'w':
|
|
116
|
-
self.__db_key = const.DEFAULT_DB_KEY
|
|
117
|
-
elif rw == 'r':
|
|
118
|
-
self.__db_key = const.READONLY_DB_KEY
|
|
119
|
-
engine = self.__get_db_engine(self.__db_key, **settings)
|
|
120
|
-
self.__engine = engine
|
|
121
|
-
self.need_commit = need_commit
|
|
122
|
-
|
|
123
|
-
# @property
|
|
124
|
-
# def db_key(self):
|
|
125
|
-
# return self.__db_key
|
|
126
|
-
|
|
127
|
-
@staticmethod
|
|
128
|
-
def __get_db_engine(db_key, **settings):
|
|
129
|
-
if len(engines) == 0:
|
|
130
|
-
init_engine_v2(**settings)
|
|
131
|
-
return engines[db_key]
|
|
132
|
-
|
|
133
|
-
@property
|
|
134
|
-
def session(self):
|
|
135
|
-
return self.__session
|
|
136
|
-
|
|
137
|
-
def __enter__(self):
|
|
138
|
-
self.__session = sessionmaker(bind=self.__engine)()
|
|
139
|
-
return self.__session
|
|
140
|
-
|
|
141
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
142
|
-
if self.need_commit:
|
|
143
|
-
if exc_type:
|
|
144
|
-
self.__session.rollback()
|
|
145
|
-
else:
|
|
146
|
-
self.__session.commit()
|
|
147
|
-
self.__session.close()
|
|
148
|
-
|
|
149
|
-
def get_session(self):
|
|
150
|
-
return self.__session
|
|
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
|
|
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
|
|
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
|
|
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
|