多业务线下Flask-Sqlalchemy使用

33 阅读1分钟

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. 注意点

  1. 事务: 如果进行数据更新与保存时,需要关注与之前的db实例看是否需要保证在同一事务之中。
  2. 考虑多业务线时 需要进行可配置?用于其余业务线服务的复用。