1. 背景
我们在查询数据时 需要使用到公共字段例如业务线字段product_line但我们只想查询AAA
。这时候如果在所有的查询条件上都加上AAA
的话逻辑太过分散,所以我们采用中间拦截方式进行重写model.query进行批量更改查询时的语句。
2. 具体代码
from sqlalchemy import orm
from sqlalchemy.orm.exc import UnmappedClassError
class PlSQLAlchemy(SQLAlchemy):
class PlQueryProperty(object):
def __init__(self, sa):
self.sa = sa
def __get__(self, obj, type):
try:
mapper = orm.class_mapper(type)
if mapper:
return type.query_class(mapper, session=self.sa.session()).filter_by(product_line='AAA
except UnmappedClassError:
return None
def make_declarative_base(self, model, metadata=None):
model = super().make_declarative_base(model, metadata)
model.query = self.PlQueryProperty(self)
return model
db = SQLAlchemy(session_options={'autocommit': True})
pl_db = PlSQLAlchemy(session_options={'autocommit': True})
#### 加载到APP
# 初始化DB
db.init_app(app)
# 初始化产品线DB
pl_db.init_app(app)
#### 模型使用pl_db
class UserInfo(pl_db.Model):
__bind_key__ = 'xxx'
__tablename__ = 'user_info'
id = db.Column(db.Integer, primary_key=True, index=True)
product_line = db.Column(db.String(8), nullable=False, server_default=db.FetchedValue(), info='产品线')
name = db.Column(db.String(64), nullable=False, info='姓名')
3. 注意点
- 事务: 如果进行数据更新与保存时,需要关注与之前的db实例看是否需要保证在同一事务之中。
- 考虑多业务线时 需要进行可配置?用于其余业务线服务的复用。