Sqlalchemy 如何实现一表多库? | 动态ORM
2021/10/18 2:10:05
本文主要是介绍Sqlalchemy 如何实现一表多库? | 动态ORM,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
在多区域情况下,每个区域都要一套完整的数据体系。然而管控层一般都是统一的,需要经常按照区域识别查询数据库。Sqlalchemy 提供了多库绑定功能,参考实现如下:
from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy import MetaData # 多个数据库连接配置信息 SQLALCHEMY_BINDS = { 'zbs': 'mysql://sharp:sharp@172.17.0.1:3306/zbs', 'sharp': 'mysql://sharp:sharp@172.17.0.1:3306/sharp', } app = Flask(__name__) app.config['SQLALCHEMY_BINDS'] = SQLALCHEMY_BINDS app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 由于使用了 Flask,这里就直接一起搞了 db = SQLAlchemy(app) class ZbsVolume(db.Model): # 指定要连接的数据库 __bind_key__ = 'zbs' # 指定对应的表名,默认是类名,这莫办法的事 __tablename__ = 'volume' # 不然会爆表名冲突,无法初始化 metadata = MetaData() id = db.Column(db.String(36), primary_key=True) volume_type_name = db.Column(db.String(255)) class SharpVolume(db.Model): __bind_key__ = 'sharp' __tablename__ = 'volume' metadata = MetaData() id = db.Column(db.String(36), primary_key=True) volume_type_name = db.Column(db.String(255))
定义好ORM,那使用就简单了,参考如下:
# 初始化数据库连接 db.create_all() ZbsVolume.query.filter_by(id='fake').first() # 新增一个 query = ZbsVolume(id=line, volume_type_name='hdd.std2) db.session.add(query)
只有1个表两个库,这么写写也直观,如果要查 N 个表,又有 M 个库,这真成了无感情的机器人了。
动态生成 Model
这时候是不是想起来了类也是可以创建的,一个简单的元类不就行了,那我们就试试看
定义一个 meta.py 文件,用来存在原始表信息
from sqlalchemy import MetaData, Column, String, Integer VolumeMeta = { '__tablename__': 'volume', '__table_args__': {'extend_existing': True}, 'metadata': MetaData(), 'id': Column(String(36), primary_key=True), 'volume_type_name': Column(String(255)), }
定义 model.py,用来创建 model
class ModelFactor(object): def __init__(self): self.cache = {} self.regions = config.ZBS_MYSQL_MAP.keys() self.meta_dict = { 'Volume': VolumeMeta, 'fake1": FakeMeta, } @classmethod def make_model_key(cls, region, model): return '%s_%s' % (region, model) def create_model(self, region, model): if model not in self.meta_dict: logger.error("model <%s> not define" % model) return None if region not in self.regions: logger.error("region <%s> not define" % region) return None db = init_db() meta = self.meta_dict[model] meta['__bind_key__'] = region logger.info("Now create model <%s_%s>" % (region, model)) return type(model, (db.Model,), meta) def select_model(self, region, model): key = self.make_model_key(region, model) if key not in self.cache: model = self.create_model(region, model) if model: self.cache[key] = model else: model = self.cache[key] return model
使用
model_factor = ModelFactor() model = model_factor.select_model(region, 'Volume') # 开始 orm 操作
这篇关于Sqlalchemy 如何实现一表多库? | 动态ORM的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-04el-table 开启定时器下,表格的选中状态会消失是什么原因-icode9专业技术文章分享
- 2024-10-03如何安装和初始化飞牛私有云 fnOS?-icode9专业技术文章分享
- 2024-10-03如何安装 App 并连接到飞牛 NAS?-icode9专业技术文章分享
- 2024-10-03如何安装飞牛 TV 并连接到影视服务器?-icode9专业技术文章分享
- 2024-10-03如何在PVE和ESXI上安装飞牛私有云 fnOS?-icode9专业技术文章分享
- 2024-10-03fnOS国产最强NAS安装系统异常情况处理-icode9专业技术文章分享
- 2024-10-03飞牛NAS如何创建存储空间?-icode9专业技术文章分享
- 2024-10-03fnOS国产最强NAS硬盘会自动休眠吗?-icode9专业技术文章分享
- 2024-10-03fnOS国产最强NAS如何安装飞牛影视和创建媒体库?-icode9专业技术文章分享
- 2024-10-03fnOS国产最强NAS如何为家人朋友开通影视账号?-icode9专业技术文章分享