账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    动态绑定flask-sqlalchemy的model
    61
    0

    背景

    用Flask实现一个REST微服务,多个结构相同的MySQL数据库对应着同一个Model。需要根据请求,在不同的数据库中作查询并返回结果。

    已完成的工作

    根据官方文档配置了SQLALCHEMY_BINDS,如:

    SQLALCHEMY_BINDS = {
            'db01': 'mysql://...',
            'db02': 'mysql://...',
            'db03': 'mysql://...'
        }

    查询时根据请求中包含的数据库名称字段动态查询:

    ...
    engine = db.get_engine(bind=db_name) #绑定数据库
    DBSession = sessionmaker(bind=engine)
    db_session = DBSession()
    result = db_session.query(db_model).filter(...).all()
    db_session.close()
    ...

    问题

    现在不单单要提供RESTful API,还要做一个将查询结果分页展示的前端页面,查阅资料可以用flask-sqlalchemy支持的paginate()来做。然而问题来了,我上面这样调用db_session.query()得到的Query对象是flask-sqlalchemy的Query父类,不支持paginate()方法。想要调用paginate()应该是:

    result = db_model.query.filter_by(...).paginate()

    而Model默认的bind应该来自app.config中的SQLALCHEMY_DATABASE_URI,我这里为None必然导致抛出异常。这样一来,engine/bind的初始化又该在哪里做?而要动态地改变db_model的bind,又该如何实现呢?

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • ソ记忆扯散流年 普通会员 1楼

      在Flask-SQLAlchemy中,你可以使用relationship属性来动态绑定模型。以下是一个简单的例子:

      ```python from flask_sqlalchemy import SQLAlchemy

      db = SQLAlchemy()

      class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True) email = db.Column(db.String(120), unique=True)

      class Category(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80))

      class Product(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80)) category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False) ```

      在这个例子中,我们定义了三个模型:User,Category和Product。每个模型都有一个ID,一个名字和一个电子邮件字段。

      然后,在我们的Flask应用中,我们可以在视图函数中使用relationship属性来动态绑定模型。例如,我们可以显示所有用户:

      ```python from flask import Flask, render_template, request

      app = Flask(name)

      @app.route('/') def index(): users = User.query.all() return render_template('index.html', users=users)

      @app.route('/add', methods=['POST']) def add(): name = request.form['name'] email = request.form['email'] user = User(name=name, email=email) db.session.add(user) db.session.commit() return redirect('/') ```

      在这个例子中,我们首先获取所有用户,然后在POST请求中添加一个新的用户。relationship属性使我们可以动态地将模型的引用添加到视图函数中,这使得我们可以方便地在视图函数中使用这些模型。

      注意,relationship属性的值应该是模型的引用,而不是模型的实例。这是因为当我们动态地添加一个新的用户时,我们实际上是在操作模型的引用,而不是模型的实例。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部