【问题标题】:flask-admin different view for multiple databasesflask-admin 多个数据库的不同视图
【发布时间】:2021-08-21 20:22:19
【问题描述】:

我有两个不同的数据库。它们是:库存和商品。每个数据库有两个表,如下:

Stock: User_trade_stock, stock_prices
Commodity: User_trade_commodity, commodity_prices

我尝试构建一个 Web 应用程序来使用烧瓶处理两个数据库。当我按如下方式向他们应用烧瓶管理员时

admin.add_view(UserView(User_trade_stock, db.session))
admin.add_view(UserView(User_trade_commodity, db.session))

我给出了以下错误:

Assertion Error: A name collision occurred between blueprints. Blueprints that are created on the fly need unique name. 

我尝试将绑定添加到 db.session,如下所示

admin.add_view(UserView(User_trade_stock, db.session(bind='stock_bind')))
admin.add_view(UserView(User_trade_commodity, db.session='commodity_bind')))

我收到以下错误:

scoped session is already present; no new arguments may be specified

任何帮助将不胜感激

【问题讨论】:

    标签: flask flask-sqlalchemy flask-admin


    【解决方案1】:

    有几个问题。

    Flask-Admin 使用视图的小写类名作为自动生成的蓝图名称。当您使用 UserView 两次时,您会遇到蓝图名称冲突。为了克服这个问题,您可以在实例化视图时指定 endpoint 名称,例如:

    admin = Admin(app, template_mode="bootstrap3")
    admin.add_view(TestView(StockTest, db.session, category='Stock', name='Test', endpoint='stock-test'))
    admin.add_view(TestView(CommodityTest, db.session, category='Commodity', name='Test', endpoint='commodity-test'))
    

    要获取视图的 url,您可以使用以下代码:

    url_for('stock-test.index')
    url_for('stock-test.edit')
    url_for('commodity-test.index')
    url_for('commodity-test.edit')
    

    其次,如果你想使用Flask-Sqlalchemy的bind feature你应该在表模型上使用__bind_key__属性,例如:

    class User(db.Model):
        __bind_key__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(80), unique=True)
    

    这是一个说明这两个概念的单个文件示例。在使用应用程序本身之前,您需要运行烧瓶命令 flask create-databasesflask populate-databases。请注意,我使用了一个 mixin 类 TestMixin 来定义模型列。

    import click
    from flask import Flask
    from flask.cli import with_appcontext
    from flask_sqlalchemy import SQLAlchemy
    from flask_admin import Admin
    from flask_admin.contrib.sqla import ModelView
    from faker import Faker
    from sqlalchemy import Integer, Column, Text
    
    db = SQLAlchemy()
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = '123456790'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    app.config['SQLALCHEMY_BINDS'] = {
        'stock': 'sqlite:///stock.db',
        'commodity': 'sqlite:///commodity.db'
    }
    
    db.init_app(app)
    
    
    class TestMixin(object):
        id = Column(Integer, primary_key=True)
        name = Column(Text(), unique=True, nullable=False)
    
    
    class StockTest(db.Model, TestMixin):
        __bind_key__ = 'stock'
    
    
    class CommodityTest(db.Model, TestMixin):
        __bind_key__ = 'commodity'
    
    
    @click.command('create-databases')
    @with_appcontext
    def create_databases():
        db.drop_all(bind=['stock', 'commodity'])
        db.create_all(bind=['stock', 'commodity'])
    
    
    @click.command('populate-databases')
    @with_appcontext
    def populate_databases():
        _faker = Faker()
        db.session.bulk_insert_mappings(StockTest, [{'name': _faker.name()} for _ in range(100)])
        db.session.bulk_insert_mappings(CommodityTest, [{'name': _faker.name()} for _ in range(100)])
        db.session.commit()
    
    
    class TestView(ModelView):
        pass
    
    
    app.cli.add_command(create_databases)
    app.cli.add_command(populate_databases)
    
    admin = Admin(app, template_mode="bootstrap3")
    admin.add_view(TestView(StockTest, db.session, category='Stock', name='Test', endpoint='stock-test'))
    admin.add_view(TestView(CommodityTest, db.session, category='Commodity', name='Test', endpoint='commodity-test'))
    
    
    @app.route('/')
    def index():
        return '<a href="/admin/">Click me to get to Admin!</a>'
    
    
    if __name__ == '__main__':
        app.run()
    

    【讨论】:

    • 谢谢。我会试一试。
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多