简体   繁体   中英

Is there a way to add mySQL database/schema name in flask sqlalchemy connection

I have a flask restful app connected to mySQL database and I am using SQLAlchemy. We can connect to the mySQL server using the following -

app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://root:password@127.0.0.1:3306"

I am working on a use case where the database name will be provided on real-time basis through a GET request. Based on the database name provided, the app will connect to the respective database and perform the operations. For this purpose, I would like to have a way where I can tell the flask app to talk to the provided database (Flask app is already connected to the mySQL server). Currently, I am creating the connection again in the API class.

API: Calculate.py

from flask_restful import Resource, reqparse
from app import app


class Calculate(Resource):

    def get(self):

        parser = reqparse.RequestParser()
        parser.add_argument('schema', type=str, required=True, help='Provide schema name.')
        args = parser.parse_args()

        session['schema_name'] = args.get('schema')

        app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://root:password@127.0.0.1:3306/{session['schema_name']}"

        from db_models.User import User

        ...

DB Model: User.py

from flask import session
from flask_sqlalchemy import SQLAlchemy
from app import app

db = SQLAlchemy(app)


class User(db.Model):

    __tablename__ = 'user'
    __table_args__ = {"schema": session['schema_name']}

    User_ID = db.Column(db.Integer, primary_key=True)
    Name    = db.Column(db.String(50))

db.create_all()

The above thing works for me. But I would want to understand if there is an alternative to this or a better way of doing this.

Edit: The above code does not work. It references the first schema name that was provided even if I provide a new schema name in the same running instance of the app.

you can write the SQLALCHEMY path like this:

SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:password@localhost:3306/database name'

According to the docs not all values can be updated (first parragraph), in your use case you should use SQLALCHEMY_BINDS variable in your use case this is a dict and create a Model for each schema. Example:

Db Model

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://root:password@127.0.0.1:3306/schema_name1"
SQLALCHEMY_BINDS = {
    'db1': SQLALCHEMY_DATABASE_URI, # default
    'db2': f"mysql+pymysql://root:password@127.0.0.1:3306/schema_name2"
}

app = Flask(__name__)
db = SQLALchemy(app)

then create a model for each schema

class UserModeldb1(db.Model):

  __tablename__ = 'user'
  __bind_key__ = 'db1' #this parameter is set according to the database

  id = db.Column(db.Integer, primary_key=True)
  ...


class UserModeldb2(db.Model):

  __tablename__ = 'user'
  __bind_key__ = 'db2'

  id = db.Column(db.Integer, primary_key=True)
...

finally in your get method add some logic to capture the schema and execute your model accorddingly. you should look this question is really helpful Configuring Flask-SQLAlchemy to use multiple databases with Flask-Restless

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM