flask管理多个数据库的不同视图



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

Stock: User_trade_stock, stock_prices
Commodity: User_trade_commodity, commodity_prices

我试着构建一个网络应用程序,用flask处理两个数据库。当我将烧瓶管理应用于他们时,如下

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

我给出以下eror:

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, 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_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, 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()

最新更新