Search code examples
mysqlpython-3.xflasksqlalchemypymysql

Create SQLAlchemy mysql connection string from input


I'm new to python. I am trying to create a connection string to a mysql, but from an input via a webform. My first thought was to create a function to call to pass in the details. Here is what I have:

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
import pymysql

app = Flask(__name__)

def db_connection(user, password, ep, db):
    connection = f"mysql+pymysql://{user}:{password}@{ep}/{db}"
    app.config['SQLALCHEMY_DATABASE_URI'] = connection
    app.config['SQLALCHEMY_TRACK_MODIFICATION'] = False
    db = SQLAlchemy(app)

    class Lab(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        store = db.Column(db.String(80), unique=True, nullable=False)
        item = db.Column(db.String(120), unique=True, nullable=False)
        quantity = db.Column(db.Integer, nullable=False)

    db.create_all()

The details of the "user", "password", "ep" (endpoint/hostname), "db" for the db_connection function are passed in via filling out a webform.

I think i might be going about this the wrong way. The end result that I want is for my user to go to the webform, fill the details about the DB to connect to, click submit then the function(or what ever) would establish the connection with those details.

The form I have passes to an app.route to establish to call the above function

@app.route('/save_settings', methods=["GET", "POST"])
def save_settings():

    ep_data = request.form['endpoint']
    db_data = request.form['database']
    user_data = request.form['username']
    password_data = request.form['password']
    db_connection(user=user_data, password=password_data, db=db_data, ep=ep_data)

When I try it, I get the following error:

AssertionError: A setup function was called after the first request was handled.  This usually indicates a bug in the application where a module was not imported and decorators or other functionality was called too late.
To fix this make sure to import all your view modules, database models and everything related at a central place before the application starts serving requests.

Solution

  • Ok, after some playing around I seemed to have fixed it. I hope this helps others that were stuck on this too. The mistakes I made:

    • the class does not come under the function
    • before the class needs to have: db = SQLAlchemy(app)

    Here is my modified code:

    from flask import Flask, render_template, request, redirect, url_for
    from flask_sqlalchemy import SQLAlchemy
    import pymysql
    
    app = Flask(__name__)
    db = SQLAlchemy(app)
    
    
    def db_connection(user, password, ep, db):
        connection = f"mysql+pymysql://{user}:{password}@{ep}/{db}"
        app.config['SQLALCHEMY_DATABASE_URI'] = connection
        app.config['SQLALCHEMY_TRACK_MODIFICATION'] = False
    
    
    class Lab(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        store = db.Column(db.String(80), unique=True, nullable=False)
        item = db.Column(db.String(120), unique=True, nullable=False)
        quantity = db.Column(db.Integer, nullable=False)