diff --git a/README.en.md b/README.en.md index 96f81fb..9064acb 100644 --- a/README.en.md +++ b/README.en.md @@ -2,119 +2,246 @@ * T = Tornado * Rest = Restful -#### Description -Web MVC framework based on Tornado combined with asyncio +#### 介绍 +基于Tornado结合asyncio的web mvc框架 -#### Software Architecture -Software architecture description +依赖 Tornado SQLAlchemy pycryptodome pytz 等 -#### Installation +* 开发约定 [https://gitee.com/leeyi/trest/blob/main/promise.md](https://gitee.com/leeyi/trest/blob/main/promise.md) +* 其他约定遵从[Python风格规范](http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_language_rules/) 、 [Python 编码规范](http://liyangliang.me/posts/2015/08/simple-python-style-guide/) -Put the following line of code into the Pipfile file [packages] -> trest = {editable = true,git = "https://gitee.com/leeyi/trest.git",ref = "master"} +#### 软件架构 +``` +tree -I '*svn|*node_module*|*git|py3|*.pyc|__pycache__|statics' +. +├── LICENSE +├── Pipfile +├── README.md +├── applications +│   ├── common +│   │   ├── const.py +│   │   ├── models +│   │   │   └── *.py +│   │   ├── assemblers +│   │   │   └── *.py +│   │   ├── services +│   │   │   └── *.py +│   │   └── utils.py +│   ├── app1 +│   │   ├── handlers +│   │   │   └── *.py +│   │   ├── models +│   │   │   └── *.py +│   │   ├── modules.py +│   │   ├── services +│   │   │   └── *.py +│   │   ├── assemblers +│   │   │   └── *.py +│   │   ├── templates +│   │   │   └── */*.html +│   │   └── utils.py +│   └── app2 +│   └── app3 +├── configs +│   ├── dev.yaml +│   └── local.yaml +├── datas +│   ├── locales +│   │   ├── en_US.csv +│   │   └── zh_CN.csv +│   ├── menu +│   │   └── menu0.json +│   ├── mysql +│   │   └── *.sql +│   ├── nginx_vhost.conf +│   ├── production_deploy.md +│   ├── supervisor_tornado.conf +│   └── supervisord.conf +├── logs +│   └── *.log +├── server.py +└── tests + └── *_test.py +``` +软件架构说明 + +* .env 环境配置文件,只有一个section [sys],一个变量 RUNTIME_ENV +* configs 应用配置文件 + * configs/local.yaml 本地开发环境相关配置 + * configs/dev.yaml 开发环境相关配置 + * configs/test.yaml 测试环境相关配置 + * configs/product.yaml 生产环境相关配置 +* applications 应用rest api相关代码 + * applications/common/models 公共应用数据模型层 + * applications/common/services 公共应用服务层 + * applications/common/assemblers 公共组装器层 + * applications/common/const.py 公共应用常量 + * applications/common/utils.py 公共应用助手函数 + * applications/app1 独立应用 + * applications/app1/handlers app1用控制器层,有路由器调用,负责接收并且校验参数 + * applications/app1/services app1应用服务层,在控制器里面调用,负责一个业务逻辑 + * applications/app1/models app1用数据模型层,在服务层调用,负责对一个数据库表CURD操作 + * applications/app1/assemblers app1组装器层,在控制器里面调用,负责把服务层数据响应给API + * applications/app1/templates app1应用视图层,渲染service数据 +* datas 数据 + * datas/locales 多语言数据 + * datas/json JSON数据文件 + * datas/sql SQL数据文件 + * \*\.* 其他数据文件 +* logs 日志文件 +* statics Web静态资源 +* tests 测试脚本 +* server.py 项目入口文件 +* README.md 项目说明文件 +* Pipfile pipenv配置文件 +* LICENSE 开源许可证 +* .gitignore Git忽略文件 + +#### 安装教程 + +把下面一行代码放入Pipfile文件 [packages]下面 +> trest = {editable = true,git = "https://gitee.com/leeyi/trest.git",ref = "main"} + +或者直接 +> pipenv install -e git+https://gitee.com/leeyi/trest.git@main#egg=trest + +或者 +> pip install git+https://gitee.com/leeyi/trest.git + +#### 使用说明 +参考 下面Demo项目, + +在项目根目录( ROOT_PATH )下面创建 server.py 文件 +``` +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import os +import sys +import resource +resource.setrlimit(resource.RLIMIT_NOFILE, (10240, 9223372036854775807)) + +from tornado.options import define + +abs_file = os.path.abspath(sys.argv[0]) +ROOT_PATH = abs_file[:abs_file.rfind('/')] +define('ROOT_PATH', ROOT_PATH) + +# 把当前目录添加到 sys.path 开头 +sys.path.insert(0, ROOT_PATH) -or -> pipenv install -e git+https://gitee.com/leeyi/trest.git@master#egg=trest +from trest.webserver import run -or -> pip install git+https://gitee.com/leeyi/trest.git#egg=trest -#### Instructions -After pipenv install under the root directory, add server.py +if __name__ == "__main__": + try: + server = run() + except KeyboardInterrupt: + sys.exit(0) + +``` + +在 项目根目录( ROOT_PATH ) 下面创建 [.env 文件](https://gitee.com/leeyi/trest/blob/main/demo_dot.env) +``` +# RUNTIME_ENV is not one of the local, dev, test, or product +# the colon must have Spaces around it +RUNTIME_ENV : local +``` run ``` +pipenv install --skip-lock pipenv shell -python server.py --port 8080 +python server.py --port=5080 +python tests/app_demo/server.py --port=5081 ``` -##### The API response -Use the raise JsonError wherever -``` -from trest.exception import JsonError +f'{ROOT_PATH}/configs/{env}.yaml' demo -raise JsonError('msg') -raise JsonError('msg', 0) -raise JsonError('msg', 1, []) -raise JsonError('msg', 1, [1,2,3]) -``` +like this [./tests/app_demo/configs/dev.yaml](https://gitee.com/leeyi/trest/blob/main/tests/app_demo/configs/dev.yaml) + +# [开发约定](https://gitee.com/leeyi/trest/blob/main/promise.md) + +* 开发约定 [https://gitee.com/leeyi/trest/blob/main/promise.md](https://gitee.com/leeyi/trest/blob/main/promise.md) +* 其他约定遵从[Python风格规范](http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_language_rules/) 、 [Python 编码规范](http://liyangliang.me/posts/2015/08/simple-python-style-guide/) #### Demo * [https://gitee.com/leeyi/py_admin](https://gitee.com/leeyi/py_admin/tree/dev/) ``` -from trest.exception import JsonError +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +[description] +""" +from trest.router import put from trest.router import get -from trest.router import delete from trest.router import post -from trest.router import put +from trest.router import delete +from trest.handler import Handler +from trest.exception import JsonError -""" -in applications/admin/handlers/abcd.py -# file name not start with _ and method name is unique -url like this, - /admin/welcome - /admin/welcome2 - /welcome3 - /admin/welcome4 -""" -class WelcomeHandler(CommonHandler): - @get('welcome') - @required_permissions() - @tornado.web.authenticated - def welcome_get(self, *args, **kwargs): - """后台首页 - """ - # menu = AdminMenu.main_menu() - # print('menu ', menu) - # self.show('abc') - params = { - } - self.render('dashboard/welcome.html', **params) - - @get('welcome2') - @required_permissions() - @tornado.web.authenticated - def welcome_get2(self, *args, **kwargs): - """后台首页 - """ - self.success(data=['welcome2']) - - @get('/welcome3') - @required_permissions() - @tornado.web.authenticated - def welcome_get(self, *args, **kwargs): - """后台首页 - """ - self.success(data=['welcome3']) - - @post('welcome4') - @required_permissions() - @tornado.web.authenticated - def welcome_post(self, *args, **kwargs): - """后台首页 - """ - self.success(data=['welcome3']) +class DemoHandler(Handler): + @post('demo0') + def add(self): + return self.success(data = ['post', 'demo0']) + +class Demo1Handler(Handler): + @post('demo1') + def add(self): + return self.success(data = ['post', 'demo1']) + +class Demo2Handler(Handler): + @get('demo2') + def get_demo2(self): + return self.success(data = ['get', 'demo2', ]) + + @get('demo2') + def get_demo2(self): + return self.success(data = ['get', 'demo23', ]) + + @delete('demo3/(?P\d*)') + def del_demo3(self, id): + return self.success(data = ['delete', 'demo3', id]) + + @delete('demo2/(?P\d*)') + def del_demo2(self, id): + return self.success(data = ['delete', 'demo2', id]) + ``` -#### Test +##### API响应 +在任意的地方使用 raise JsonError ``` -pipenv install --skip-lock +from trest.exception import JsonError + +raise JsonError('msg') +raise JsonError('msg', 0) +raise JsonError('msg', 1, []) +raise JsonError('msg', 1, [1,2,3]) ``` -#### Contribution +#### 避免 master/slave 等术语 + +Old | New | 说明 +---|---|--- +master | main | 主要的 +slave | subordinate | 从属的 +blacklist | denylist | 拒绝名单 +whitelist | allowlist | 允许名单 + +#### 参与贡献 -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request -#### Gitee Feature +#### 码云特技 -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 +5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 6b260ee..9064acb 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ 依赖 Tornado SQLAlchemy pycryptodome pytz 等 -* 开发约定 [https://gitee.com/leeyi/trest/blob/master/promise.md](https://gitee.com/leeyi/trest/blob/master/promise.md) +* 开发约定 [https://gitee.com/leeyi/trest/blob/main/promise.md](https://gitee.com/leeyi/trest/blob/main/promise.md) * 其他约定遵从[Python风格规范](http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_language_rules/) 、 [Python 编码规范](http://liyangliang.me/posts/2015/08/simple-python-style-guide/) #### 软件架构 @@ -100,10 +100,10 @@ tree -I '*svn|*node_module*|*git|py3|*.pyc|__pycache__|statics' #### 安装教程 把下面一行代码放入Pipfile文件 [packages]下面 -> trest = {editable = true,git = "https://gitee.com/leeyi/trest.git",ref = "master"} +> trest = {editable = true,git = "https://gitee.com/leeyi/trest.git",ref = "main"} 或者直接 -> pipenv install -e git+https://gitee.com/leeyi/trest.git@master#egg=trest +> pipenv install -e git+https://gitee.com/leeyi/trest.git@main#egg=trest 或者 > pip install git+https://gitee.com/leeyi/trest.git @@ -140,7 +140,7 @@ if __name__ == "__main__": ``` -在 项目根目录( ROOT_PATH ) 下面创建 [.env 文件](https://gitee.com/leeyi/trest/blob/master/demo_dot.env) +在 项目根目录( ROOT_PATH ) 下面创建 [.env 文件](https://gitee.com/leeyi/trest/blob/main/demo_dot.env) ``` # RUNTIME_ENV is not one of the local, dev, test, or product # the colon must have Spaces around it @@ -157,11 +157,11 @@ python tests/app_demo/server.py --port=5081 f'{ROOT_PATH}/configs/{env}.yaml' demo -like this [./tests/app_demo/configs/dev.yaml](https://gitee.com/leeyi/trest/blob/master/tests/app_demo/configs/dev.yaml) +like this [./tests/app_demo/configs/dev.yaml](https://gitee.com/leeyi/trest/blob/main/tests/app_demo/configs/dev.yaml) -# [开发约定](https://gitee.com/leeyi/trest/blob/master/promise.md) +# [开发约定](https://gitee.com/leeyi/trest/blob/main/promise.md) -* 开发约定 [https://gitee.com/leeyi/trest/blob/master/promise.md](https://gitee.com/leeyi/trest/blob/master/promise.md) +* 开发约定 [https://gitee.com/leeyi/trest/blob/main/promise.md](https://gitee.com/leeyi/trest/blob/main/promise.md) * 其他约定遵从[Python风格规范](http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_language_rules/) 、 [Python 编码规范](http://liyangliang.me/posts/2015/08/simple-python-style-guide/) #### Demo @@ -220,6 +220,15 @@ raise JsonError('msg', 1, []) raise JsonError('msg', 1, [1,2,3]) ``` +#### 避免 master/slave 等术语 + +Old | New | 说明 +---|---|--- +master | main | 主要的 +slave | subordinate | 从属的 +blacklist | denylist | 拒绝名单 +whitelist | allowlist | 允许名单 + #### 参与贡献 1. Fork 本仓库 diff --git a/README_zh.md b/README_zh.md index 6b260ee..9064acb 100644 --- a/README_zh.md +++ b/README_zh.md @@ -7,7 +7,7 @@ 依赖 Tornado SQLAlchemy pycryptodome pytz 等 -* 开发约定 [https://gitee.com/leeyi/trest/blob/master/promise.md](https://gitee.com/leeyi/trest/blob/master/promise.md) +* 开发约定 [https://gitee.com/leeyi/trest/blob/main/promise.md](https://gitee.com/leeyi/trest/blob/main/promise.md) * 其他约定遵从[Python风格规范](http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_language_rules/) 、 [Python 编码规范](http://liyangliang.me/posts/2015/08/simple-python-style-guide/) #### 软件架构 @@ -100,10 +100,10 @@ tree -I '*svn|*node_module*|*git|py3|*.pyc|__pycache__|statics' #### 安装教程 把下面一行代码放入Pipfile文件 [packages]下面 -> trest = {editable = true,git = "https://gitee.com/leeyi/trest.git",ref = "master"} +> trest = {editable = true,git = "https://gitee.com/leeyi/trest.git",ref = "main"} 或者直接 -> pipenv install -e git+https://gitee.com/leeyi/trest.git@master#egg=trest +> pipenv install -e git+https://gitee.com/leeyi/trest.git@main#egg=trest 或者 > pip install git+https://gitee.com/leeyi/trest.git @@ -140,7 +140,7 @@ if __name__ == "__main__": ``` -在 项目根目录( ROOT_PATH ) 下面创建 [.env 文件](https://gitee.com/leeyi/trest/blob/master/demo_dot.env) +在 项目根目录( ROOT_PATH ) 下面创建 [.env 文件](https://gitee.com/leeyi/trest/blob/main/demo_dot.env) ``` # RUNTIME_ENV is not one of the local, dev, test, or product # the colon must have Spaces around it @@ -157,11 +157,11 @@ python tests/app_demo/server.py --port=5081 f'{ROOT_PATH}/configs/{env}.yaml' demo -like this [./tests/app_demo/configs/dev.yaml](https://gitee.com/leeyi/trest/blob/master/tests/app_demo/configs/dev.yaml) +like this [./tests/app_demo/configs/dev.yaml](https://gitee.com/leeyi/trest/blob/main/tests/app_demo/configs/dev.yaml) -# [开发约定](https://gitee.com/leeyi/trest/blob/master/promise.md) +# [开发约定](https://gitee.com/leeyi/trest/blob/main/promise.md) -* 开发约定 [https://gitee.com/leeyi/trest/blob/master/promise.md](https://gitee.com/leeyi/trest/blob/master/promise.md) +* 开发约定 [https://gitee.com/leeyi/trest/blob/main/promise.md](https://gitee.com/leeyi/trest/blob/main/promise.md) * 其他约定遵从[Python风格规范](http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_language_rules/) 、 [Python 编码规范](http://liyangliang.me/posts/2015/08/simple-python-style-guide/) #### Demo @@ -220,6 +220,15 @@ raise JsonError('msg', 1, []) raise JsonError('msg', 1, [1,2,3]) ``` +#### 避免 master/slave 等术语 + +Old | New | 说明 +---|---|--- +master | main | 主要的 +slave | subordinate | 从属的 +blacklist | denylist | 拒绝名单 +whitelist | allowlist | 允许名单 + #### 参与贡献 1. Fork 本仓库 diff --git a/tests/app_demo/configs/dev.yaml b/tests/app_demo/configs/dev.yaml index efade25..947ca2c 100644 --- a/tests/app_demo/configs/dev.yaml +++ b/tests/app_demo/configs/dev.yaml @@ -85,12 +85,12 @@ sqlalchemy : 'sqlalchemy.poolclass' : QueuePool # 数据库连接字符串,元祖, -# 每组为n个数据库连接,有且只有一个master,可配与不配slave +# 每组为n个数据库连接,有且只有一个main,可配与不配subordinate DATABASE_CONNECTION : default : connections : - - ROLE: 'master' + ROLE: 'main' DRIVER : 'mysql+mysqldb' UID : root # 进过AES加密的密码,格式 aes::: + ciphertext @@ -100,7 +100,7 @@ DATABASE_CONNECTION : DATABASE : 'db_py_admin' QUERY : {'charset' : 'utf8mb4'} - - ROLE : 'slave' + ROLE : 'subordinate' DRIVER : 'mysql+mysqldb' UID : root # 进过AES加密的密码,格式 aes::: + ciphertext diff --git a/trest/config/config.py b/trest/config/config.py index f826142..796d79a 100644 --- a/trest/config/config.py +++ b/trest/config/config.py @@ -75,12 +75,12 @@ 'sqlalchemy.poolclass' : QueuePool # 数据库连接字符串,元祖, -# 每组为n个数据库连接,有且只有一个master,可配与不配slave +# 每组为n个数据库连接,有且只有一个main,可配与不配subordinate DATABASE_CONNECTION : default : connections : - - ROLE: 'master' + ROLE: 'main' DRIVER : 'mysql+mysqldb' UID : root # 进过AES加密的密码,格式 aes::: + ciphertext @@ -90,7 +90,7 @@ DATABASE : 'db_py_admin' QUERY : {'charset' : 'utf8mb4'} - - ROLE : 'slave' + ROLE : 'subordinate' DRIVER : 'mysql+mysqldb' UID : root # 进过AES加密的密码,格式 aes::: + ciphertext diff --git a/trest/db/__init__.py b/trest/db/__init__.py index 94ac94b..b327c21 100644 --- a/trest/db/__init__.py +++ b/trest/db/__init__.py @@ -28,18 +28,18 @@ class Model(MetaBaseModel): @declared_attr def Q(cls) -> Query: - """ not using master """ + """ not using main """ return Connector.get_conn(cls.__connection_name__).query() @declared_attr def Update(cls) -> Query: - """ using master """ + """ using main """ return Connector.get_conn(cls.__connection_name__).query(True) @declared_attr def session(cls): - """ using master """ - return Connector.get_session(cls.__connection_name__)['master'] + """ using main """ + return Connector.get_session(cls.__connection_name__)['main'] def __init__(self, **kwargs): for k, v in kwargs.items(): diff --git a/trest/db/dbalchemy.py b/trest/db/dbalchemy.py index d98e9b5..ea9f082 100644 --- a/trest/db/dbalchemy.py +++ b/trest/db/dbalchemy.py @@ -33,8 +33,8 @@ _SQLALCHEMY_PREFIX = 'sqlalchemy.' _CONNECTION_TYPE = ( - 'master', - 'slave', + 'main', + 'subordinate', ) _BASE_SQLALCHEMY_CONFIGURATION = { @@ -97,8 +97,8 @@ def parser_engines(cls): engines[connection_name] = { 'kwargs': connection_item.get('kwargs', {}), - 'master': [], - 'slaves': [], + 'main': [], + 'subordinates': [], } connections_str = connection_item['connections'] @@ -112,14 +112,14 @@ def parser_engines(cls): database=conn['DATABASE'], query=conn['QUERY']) if conn['ROLE'] == _CONNECTION_TYPE[0]: - engines[connection_name]['master'].append(dburl) + engines[connection_name]['main'].append(dburl) elif conn['ROLE'] == _CONNECTION_TYPE[1]: - engines[connection_name]['slaves'].append(dburl) + engines[connection_name]['subordinates'].append(dburl) else: raise ConfigError('role %s not allowed.' % conn['ROLE']) - if not len(engines[connection_name]['master']): - raise ConfigError('conn:%s ,master connection not found.' % connection_name) + if not len(engines[connection_name]['main']): + raise ConfigError('conn:%s ,main connection not found.' % connection_name) return engines @@ -164,8 +164,8 @@ def conn_pool(self): for name, engine in engines.items(): kw = engine['kwargs'] connection_pool[name] = self.class_(config, - master_url=engine['master'], - slaves_url=engine['slaves'], + main_url=engine['main'], + subordinates_url=engine['subordinates'], session_conf=kw.pop('session', {}), **kw) except Exception as e: @@ -206,11 +206,11 @@ def paginate(self, page, per_page=20, default=None): class ConnBase(object): - def __init__(self, config=None, master_url=None, slaves_url=None, session_conf=None, **kwargs): + def __init__(self, config=None, main_url=None, subordinates_url=None, session_conf=None, **kwargs): self.kwargs = kwargs or {} self.config = config or {} - self.master_url = master_url - self.slaves_url = slaves_url or [] + self.main_url = main_url + self.subordinates_url = subordinates_url or [] self.session_conf = session_conf or {} @property @@ -221,7 +221,7 @@ def engines(self): def session(self): raise NotImplementedError - def query(self, using_master=False): + def query(self, using_main=False): raise NotImplementedError def remove(self): @@ -239,105 +239,105 @@ def ping_db(self): class SQLAlchemy(ConnBase): - def __init__(self, config=None, master_url=None, slaves_url=None, session_conf=None, **kwargs): + def __init__(self, config=None, main_url=None, subordinates_url=None, session_conf=None, **kwargs): """ 连接对象init :param base_conf: 全局配置,sqlalchemy.开头 - :param master_url: 主库连接 - :param slaves_url: 从库连接 + :param main_url: 主库连接 + :param subordinates_url: 从库连接 :param others_url: 其他类型,暂未实现 :param kwargs: 自定义配置 """ super(SQLAlchemy, self).__init__(config=config, - master_url=master_url, - slaves_url=slaves_url, + main_url=main_url, + subordinates_url=subordinates_url, session_conf=session_conf, **kwargs) # 每一个engine都会有一个factory,感觉挺闹心,要是有10个engine。。就得10个factory,未来寻找一下全局只有一个factory的方案 - self._slave_tmp = None + self._subordinate_tmp = None session_conf['query_cls'] = BaseQuery - self._master_engine = engine_from_config(self.config, prefix=_SQLALCHEMY_PREFIX, url=master_url[0], **kwargs) - self._master_session = create_session(self._master_engine, **session_conf) - self._slaves_session = [] - self._slave_engine = [] + self._main_engine = engine_from_config(self.config, prefix=_SQLALCHEMY_PREFIX, url=main_url[0], **kwargs) + self._main_session = create_session(self._main_engine, **session_conf) + self._subordinates_session = [] + self._subordinate_engine = [] - for slave in slaves_url: - slave_engine = engine_from_config(self.config, prefix=_SQLALCHEMY_PREFIX, url=slave, **kwargs) - self._slave_engine.append(slave_engine) - self._slaves_session.append(create_session(slave_engine, **session_conf)) + for subordinate in subordinates_url: + subordinate_engine = engine_from_config(self.config, prefix=_SQLALCHEMY_PREFIX, url=subordinate, **kwargs) + self._subordinate_engine.append(subordinate_engine) + self._subordinates_session.append(create_session(subordinate_engine, **session_conf)) def remove(self): # 连接释放通过可通过中间件提供,用户可自行决定是否要使用 - self._master_session.remove() - if self._slaves_session: - for slave in self._slaves_session: - slave.remove() - self._slave_tmp = None + self._main_session.remove() + if self._subordinates_session: + for subordinate in self._subordinates_session: + subordinate.remove() + self._subordinate_tmp = None @property def session(self): return { - 'master': self.using_master_session(), - 'slave': self.using_slave_session() + 'main': self.using_main_session(), + 'subordinate': self.using_subordinate_session() } - def using_master_session(self): + def using_main_session(self): """ 主库session """ - return self._master_session + return self._main_session @property def engines(self): return { - 'master': self._master_engine, - 'slaves': self._slave_engine + 'main': self._main_engine, + 'subordinates': self._subordinate_engine } - def using_slave_session(self): + def using_subordinate_session(self): """ 从库session """ - if not self._slave_tmp: - if self._slaves_session: - self._slave_tmp = random.choice(self._slaves_session) + if not self._subordinate_tmp: + if self._subordinates_session: + self._subordinate_tmp = random.choice(self._subordinates_session) else: - self._slave_tmp = self._master_session + self._subordinate_tmp = self._main_session - return self._slave_tmp + return self._subordinate_tmp - def query(self, using_master=False): - if using_master: - return self.using_master_session().query_property(BaseQuery) + def query(self, using_main=False): + if using_main: + return self.using_main_session().query_property(BaseQuery) - if self._slaves_session: - return self.using_slave_session().query_property(BaseQuery) + if self._subordinates_session: + return self.using_subordinate_session().query_property(BaseQuery) else: - return self.using_master_session().query_property(BaseQuery) + return self.using_main_session().query_property(BaseQuery) async def ping_db(self): # 防止数据库失联,定时ping一下 ping = 'SELECT 0' try: - self._master_session.execute(ping) - self._master_session.remove() - for slave in self._slaves_session: - slave.execute(ping) - slave.remove() + self._main_session.execute(ping) + self._main_session.remove() + for subordinate in self._subordinates_session: + subordinate.execute(ping) + subordinate.remove() except Exception as ex: SysLogger.error('ping mysql error:' + str(ex)) def create_db(self): - if not self._master_engine.echo: - self._master_engine.echo = True - Model.metadata.create_all(self._master_engine) + if not self._main_engine.echo: + self._main_engine.echo = True + Model.metadata.create_all(self._main_engine) def drop_db(self): - if not self._master_engine.echo: - self._master_engine.echo = True - Model.metadata.drop_all(self._master_engine) + if not self._main_engine.echo: + self._main_engine.echo = True + Model.metadata.drop_all(self._main_engine) def get_connector(conn_class_):