微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多个数据库的flask-admin不同视图

如何解决多个数据库的flask-admin不同视图

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

Stock: User_Trade_stock,stock_prices
commodity: User_Trade_commodity,commodity_prices

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

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-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,category='Commodity',endpoint='commodity-test'))

要获取视图的网址,您将使用以下代码:

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 命令 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,endpoint='commodity-test'))


@app.route('/')
def index():
    return '<a href="/admin/">Click me to get to Admin!</a>'


if __name__ == '__main__':
    app.run()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。