【问题标题】:Seperate Database for flask admin烧瓶管理员的单独数据库
【发布时间】:2023-04-05 23:21:01
【问题描述】:

谁能告诉我,如何为 Flask 管理员和可能的 Flask 安全创建一个单独的数据库? 这就是我使用 PostgreSQL 数据库加载一些表并执行 CRUD 的方式:

import flask_admin
from flask import Flask
from sqlalchemy import create_engine


app =Flask(__name__)
engine = create_engine{'postgresql://name:password@localhost/tablesdatabase')

我希望为烧瓶管理员创建一个单独的数据库:(这就是我正在尝试的)

admin = flask_admin.Admin(app)

app.config['SQLALCHEMY_BINDS'] = {'admindb' : 'postgresql://name:password@localhost/adminedatabase'}
admin.add_view(ModelView) ? // how can i impelement this ? with a seperate datbase ?

【问题讨论】:

    标签: flask sqlalchemy flask-admin


    【解决方案1】:

    没有官方支持,但是你可以自定义Flask-SQLalchemy session来使用不同的连接,这里是使用masterslave连接的例子,你可以轻松添加任意数量的连接

    from functools import partial
    
    from sqlalchemy import orm
    from flask import current_app
    from flask_sqlalchemy import SQLAlchemy, get_state
    
    
    class RoutingSession(orm.Session):
        def __init__(self, db, autocommit=False, autoflush=True, **options):
            self.app = db.get_app()
            self.db = db
            self._bind_name = None
            orm.Session.__init__(
                self, autocommit=autocommit, autoflush=autoflush,
                bind=db.engine,
                binds=db.get_binds(self.app),
                **options,
            )
    
        def get_bind(self, mapper=None, clause=None):
            try:
                state = get_state(self.app)
            except (AssertionError, AttributeError, TypeError) as err:
                current_app.logger.info(
                    'cant get configuration. default bind. Error:' + err)
                return orm.Session.get_bind(self, mapper, clause)
    
            # If there are no binds configured, use default SQLALCHEMY_DATABASE_URI
            if not state or not self.app.config['SQLALCHEMY_BINDS']:
                return orm.Session.get_bind(self, mapper, clause)
    
            # if want to user exact bind
            if self._bind_name:
                return state.db.get_engine(self.app, bind=self._bind_name)
            else:
                # if no bind is used connect to default
                return orm.Session.get_bind(self, mapper, clause)
    
        def using_bind(self, name):
            bind_session = RoutingSession(self.db)
            vars(bind_session).update(vars(self))
            bind_session._bind_name = name
            return bind_session
    
    
    class RouteSQLAlchemy(SQLAlchemy):
        def __init__(self, *args, **kwargs):
            SQLAlchemy.__init__(self, *args, **kwargs)
            self.session.using_bind = lambda s: self.session().using_bind(s)
    
        def create_scoped_session(self, options=None):
            if options is None:
                options = {}
            scopefunc = options.pop('scopefunc', None)
            return orm.scoped_session(
                partial(RoutingSession, self, **options),
                scopefunc=scopefunc,
            )
    

    默认会话是master,当你想从slave中选择时你可以直接调用它,这里是例子:

    在您的应用中:

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql:///master'
    app.config['SQLALCHEMY_BINDS'] = {
        'slave': 'postgresql:///slave'
    }
    
    db = RouteSQLAlchemy(app)
    

    从母版中选择

    session.query(User).filter_by(id=1).first() 
    

    从奴隶中选择

    session.using_bind('slave').query(User).filter_by(id=1).first() 
    

    【讨论】:

      猜你喜欢
      • 2019-01-02
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多