• Flask-SQLAlchemy 中使用显式主主数据库设置


    在这里插入图片描述

    1、问题背景

    在一个 Flask-SQLAlchemy 项目中,用户想要使用显式主主数据库设置。具体而言,他想要能够从默认数据库中读取数据,并将数据持久化到两个主数据库中。他希望知道是否可以使用 Flask-SQLAlchemy 和 binds 来实现这一目标。

    2、解决方案

    为了实现显式主主数据库设置,可以按照以下步骤进行操作:

    1. 定义 SQLAlchemy 应用程序配置
    app = Flask(__name__)
    
    # 定义默认数据库 URI
    SQLALCHEMY_DATABASE_URI = 'default_DB_uri'
    
    # 定义主数据库 URI
    SQLALCHEMY_BINDS = { 'master1':'first_master_DB_uri', 'master2': 'second_master_DB_uri' }
    
    # 将 SQLAlchemy 配置应用到 Flask 应用中
    app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
    app.config['SQLALCHEMY_BINDS'] = SQLALCHEMY_BINDS
    
    # 创建 SQLAlchemy 对象
    db = SQLAlchemy(app)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 自定义 Flask-SQLAlchemy 会话类
    from flask_sqlalchemy import SQLAlchemy, SignallingSession, get_state
    from flask_sqlalchemy._compat import itervalues
    
    class UsingBindSignallingSession(SignallingSession):
        def get_bind(self, mapper=None, clause=None):
            if self._name:
                _eng = get_state(self.app).db.get_engine(self.app,bind=self._name)
                return _eng
            else:
                return super(UsingBindSignallingSession, self).get_bind(mapper, clause)
    
        _name = None
        def using_bind(self, name):
            self._name = name
            return self
    
    class UsingBindSQLAlchemy(SQLAlchemy):
        def create_session(self, options):
            return UsingBindSignallingSession(self, **options)
    
        def get_binds(self, app=None):
            retval = super(UsingBindSQLAlchemy, self).get_binds(app)
            # get the binds for None again in order to make sure that it is the default bind for tables
            # without an explicit bind
            bind = None
            engine = self.get_engine(app, bind)
            tables = self.get_tables_for_bind(bind)
            retval.update(dict((table, engine) for table in tables))
            return retval
    
        def get_tables_for_bind(self, bind=None):
            """Returns a list of all tables relevant for a bind.
            Tables without an explicit __bind_key__ will be bound to all binds.
            """
            result = []
            for table in itervalues(self.Model.metadata.tables):
                # if we don't have an explicit __bind_key__ bind this table to all databases
                if table.info.get('bind_key') == bind or table.info.get('bind_key') == None:
                    result.append(table)
            return result
    
    db = UsingBindSQLAlchemy()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    1. 使用自定义的 Flask-SQLAlchemy 会话类
    # 创建一个默认数据库会话
    session = db.session
    
    # 创建一个主数据库会话
    master_session1 = db.session().using_bind('master1')
    
    # 创建另一个主数据库会话
    master_session2 = db.session().using_bind('master2')
    
    # 在默认数据库中读取数据
    read_data = session.query('select ...').all()
    
    # 在第一个主数据库中持久化数据
    master_session1.add(SOME_OBJECT)
    master_session1.commit()
    
    # 在第二个主数据库中持久化数据
    master_session2.add(SOME_OBJECT_CLONE)
    master_session2.commit()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    通过上述步骤,就可以实现显式主主数据库设置,并在 Flask-SQLAlchemy 中使用它。

  • 相关阅读:
    鸡兔同笼问题python程序怎么写
    maven导入本地jar包
    【MySQL】表的约束
    为何面试官总是将你简历上的技术问题问到回答不出来为止?
    【1620. 网络信号最好的坐标】
    #安装lnmp1.5到最后出现Error: MySQL install failed的解决方法#
    杭州公积金修改手机号信息
    priority_queue 模拟实现
    sqlplus set参数大区
    JMeter元件作用域和执行顺序
  • 原文地址:https://blog.csdn.net/huakej_/article/details/138074505