Simple Flask app - can't connect to database on localhost? - python

I am trying to follow this tutorial:
http://code.tutsplus.com/tutorials/creating-a-web-app-from-scratch-using-python-flask-and-mysql--cms-22972
I have the web app appearing, i can browse between pages and when I click "Sign up" after filling in details I get this error in python:
ERROR:__main__:Exception on /signUp [POST]
OperationalError: (2003, "Can't connect to MySQL server on 'localhost' (10061)")
I'm not sure whats happening here, i have a database called "BucketList.db" in the app.py root folder.
Is there a way to find out where is is getting stuck? or why it cannot connect to the db? I can connect directly to the database using Sqlite and it all seems fine so maybe something not right with how its accessed through localhost?
Any help/guidance would be appreciated! Thanks!!
from flask import Flask, render_template, json, request
from flask_mysqldb import MySQL
from werkzeug import generate_password_hash, check_password_hash
mysql = MySQL()
app = Flask(__name__)
# MySQL configurations
app.config['MYSQL_DATABASE_DB'] = 'BucketList'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
app.config['MYSQL_DATABASE_PORT'] = '5002'
mysql.init_app(app)
#app.route('/')
def main():
return render_template('index.html')
#app.route('/showSignUp')
def showSignUp():
return render_template('signup.html')
#app.route('/signUp',methods=['POST','GET'])
def signUp():
try:
_name = request.form['inputName']
_email = request.form['inputEmail']
_password = request.form['inputPassword']
# validate the received values
if _name and _email and _password:
# All Good, let's call MySQL
conn = mysql.connect()
cursor = conn.cursor()
_hashed_password = generate_password_hash(_password)
cursor.callproc('sp_createUser',(_name,_email,_hashed_password))
data = cursor.fetchall()
if len(data) is 0:
conn.commit()
return json.dumps({'message':'User created successfully !'})
else:
return json.dumps({'error':str(data[0])})
else:
return json.dumps({'html':'<span>Enter the required fields</span>'})
except Exception as e:
return json.dumps({'error':str(e)})
finally:
cursor.close()
conn.close()
if __name__ == "__main__":
app.run(port=5002)

You may try to avoid connecting again in finally clause. Simply, write conn.close() and cursor.close(). It should resolve your problem.

Here is the code I got to work using the Sqlite implementation suggested by scrineym. It works to the point where you have an app that enters and commits to the database.
Now my only issue is the json parts arent working when I submit/get an error/no field data is written! At least theres one solution that works to the original question!
from flask import Flask, render_template, json, request
from werkzeug import generate_password_hash, check_password_hash
import sqlite3
from flask import g
DATABASE = 'BucketList.db'
#mysql = MySQL()
app = Flask(__name__)
#app.route('/')
def main():
return render_template('index.html')
#app.route('/showSignUp')
def showSignUp():
return render_template('signup.html')
#app.route('/signUp',methods=['POST','GET'])
def signUp():
_name = request.form['inputName']
_email = request.form['inputEmail']
_password = request.form['inputPassword']
# validate the received values
if _name and _email and _password:
print _name, _email
db = g._database = sqlite3.connect(DATABASE)
cursor = get_db().cursor()
print "Database opened"
_hashed_password = generate_password_hash(_password)
print _hashed_password
_userid = str(_name) + str(_hashed_password[0:4])
db.execute('INSERT INTO tbl_user VALUES (?,?,?,?)',(_userid,_name,_email,_hashed_password))
db.commit()
data = cursor.fetchall()
if len(data) is 0:
conn.commit()
return json.dumps({'message':'User created successfully !'})
else:
return json.dumps({'error':str(data[0])})
else:
return json.dumps({'html':'<span>Enter the required fields</span>'})
cursor.close()
db.close()
print "Database closed"
"Print here"
if __name__ == "__main__":
app.run(port=5002)

Related

How to configure DB in a Flask app dynamicly?

I'm working on app, where user have to enter database connection parametrs by hands
So I've made an api here it is:
from flask_mysqldb import MySQL
from flask import Flask, request
import MySQLdb.cursors
app = Flask(__name__)
# /hello
#app.route("/hello", methods=['GET'])
def hello():
return "Hello word"
# /get_tables
#app.route(f"/get_tables", methods=['GET'])
def get_tables():
host = request.args.get('host', type=str)
user = request.args.get('user', type=str)
password = request.args.get('password', type=str)
database = request.args.get('database', type=str)
app.config['MYSQL_HOST'] = "localhost"
app.config['MYSQL_USER'] = "root"
app.config['MYSQL_PASSWORD'] = "password"
app.config['MYSQL_DB'] = "restaurant"
mysql = MySQL(app)
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
query = "SHOW TABLES"
cursor.execute(query)
records = cursor.fetchone()
print(records)
return records
"hello" endpoint is working fine, but when run "get_tables" I recieve an error:
AssertionError: The setup method 'teardown_appcontext' can no longer be called on the application. It has already handled its first request, any changes will not be applied consistently. Make sure all imports, decorators, functions, etc. needed to set up the application are done before running it.
I also was trying to debug my api and found out that errorr ocures on a mysql = MySQL(app) line
What can I do to solve this problem? or maybe it's better not to use api at all and just connect to DB from ui?

Attribute Error: 'NoneType' object has no attribute 'cursor' in Python

I have this code
from flask_mysqldb import MySQL
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER']='root'
app.config['MYSQL_PASSWORD']=''
app.config['MYSQL_DB']='appdb'
mysql = MySQL(appdb)
cursor = mysql.connection.cursor()
cursor.execute("SELECT id FROM table WHERE id='Apple'")
apple= cursor.fetchone()
cursor.close()
However, I get this error
Attribute Error: Nonetype object has no attribute 'cursor'
How to solve this error?
from sqlalchemy import create_engine
from sqlalchemy.orm import close_all_sessions
import mysql.connector
import time
username = 'MYSQL_USER'
password = 'MYSQL_PASSWORD!'
host = 'MYSQL_HOST'
port = 'MYSQL_port'
DB_NAME = 'MYSQL_DBname'
engine = create_engine(f"mysql+mysqlconnector://{username}:{password}#{host}:{port}")
n = 250
for i in range(0,vac.shape[0],n):
with engine.connect() as conn:
result = conn.execute("USE MYSQL_DBname")
result = conn.execute(""SELECT id FROM table WHERE id='Apple'"")
try this one
Your parameters are in "app" not "appdb" which is why "mysql" is None, in other words no connection was made. Change it to MySQL(app).
It's better to check if the connection was made before executing a query.
from flask import Flask
from flask_mysqldb import MySQL
app = Flask(__name__)
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER']='root'
app.config['MYSQL_PASSWORD']=''
app.config['MYSQL_DB']='appdb'
mysql = MySQL(app)
if mysql:
print("Connection Successful!")
cursor = mysql.connection.cursor()
cursor.execute("SELECT id FROM table WHERE id='Apple'")
apple= cursor.fetchone()
cursor.close()
else:
print("Connection Failed!")
if __name__ == '__main__':
app.run()

error: 'MySQL' object has no attribute 'connection'/ 'MySQL' object has no attribute 'get_db'

I am new to flask and i am writing a basic program for login. Everytime I ammend i end with error mentioned above. below is my code for reference. Can someone please correct me.
#app.route('/')
def index():
return render_template('form_ex.html')
#app.route('/',methods = ['POST'])
def Authenticate():
login = request.form['u']
password = request.form['p']
cursor = mysql.get_db().cursor()
cursor.execute("SELECT * FROM UserLogin WHERE login=%s and password=%s")
data= cursor.fetchone()
if data is None:
return("Username or password incorrect")
else:
return("You are logged in")
By the looks of the code you didn't initialise the MySQL DB, taken from this link the answer is below: Using MySQL in Flask
Firstly you need to install Flask-MySQL package. Using pip for example:
pip install flask-mysql
Next you need to add some configuration and initialize MySQL:
from flask import Flask
from flaskext.mysql import MySQL
app = Flask(__name__)
mysql = MySQL()
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = 'root'
app.config['MYSQL_DATABASE_DB'] = 'EmpData'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
Now you can get connection and cursor objects and execute raw queries:
conn = mysql.connect()
cursor =conn.cursor()
cursor.execute("SELECT * from User")
data = cursor.fetchone()

Problems using sqlAlchemy to execute SQL queries on my database

I am working on a project to work on a website that connects to a mysql server using flask and sqlAlchemy (Hosted on AWS RDS) and I am following this tutorial but when I try to do (/api/bar) I get this error. When I just do my localhost:8080 it shows "Hello World" perfectly fine.
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'localhost' ([WinError 10061] No connection could be made because the target machine actively refused it)") (Background on this error at: http://sqlalche.me/e/e3q8)
config.py
database_url = "mysql+pymysql://username:password#localhost:3306/barbeerdrinker"
Here is my __init__.py
from flask import Flask
from flask import jsonify
from flask import make_response
from flask import request
import json
from barbeerdrinker import database
#Flask application
app = Flask(__name__)
#app.route("/")
def hello_world():
return "Hello World"
#app.route("/api/bar", methods=["GET"])
def get_bars():
return jsonify(database.get_bars())
#app.route("/api/bar/<name>", methods=["GETS"])
def find_bar(name):
try:
if name is None:
raise ValueError("Bar is not specified")
bar = database.find_bar(name)
if bar is None:
return make_response("No bar found within given name", 404)
return jsonify(bar)
except ValueError as e:
return make_response(str(e), 400)
except Exception as e:
return make_response(str(e), 500)
#app.route("/api/beers_cheaper_than", methods=["POST"])
def find_beers_cheaper_than():
body = json.loads(request.data)
max_price = body['maxPrice']
return jsonify(database.filter_beers(max_price))
database.py
from sqlalchemy import create_engine
from sqlalchemy import sql
from barbeerdrinker import config
engine = create_engine(config.database_url)
def get_bars():
with engine.connect() as con:
rs = con.execute("SELECT name, address, city, opening, closing, phoneNum FROM bars")
return [dict(row) for row in rs]
def find_bar(name):
with engine.connect() as con:
query = sql.text("SELECT * FROM bars WHERE name = :name;")
rs = con.execute(query, name=name)
result = rs.first()
if result is None:
return None
return dict(result)
def filter_beers(max_price):
with engine.connect() as con:
query = sql.text("SELECT * FROM sells WHERE price < : max_price;")
rs = con.execute(query, max_price=max_price)
results = [dict(row) for row in rs]
for r in results:
r['price'] = float(r['price'])
return results
**Edit: So it seems like the problem is not an issue with my code but a Windows error. One solution I tried to do was to open up the required ports through my firewall to no avail.
I just figured it out, turns out the issue is not a windows issue. The problem is within my config.py:
Instead of:
database_url = "mysql+pymysql://username:password#localhost:3306/barbeerdrinker"
It should be:
database_url = "mysql+pymysql://username:password#**AWSENDPOINT/HOSTNAME**:3306/barbeerdrinker"

UnboundLocalError: local variable 'cursor' referenced before assignment [duplicate]

This question already has answers here:
How can a name be "unbound" in Python? What code can cause an `UnboundLocalError`?
(3 answers)
How do I correctly clean up a Python object?
(11 answers)
Closed 17 days ago.
So I am a newbie but working on a registration system form in flask/MYSQL
I am receiving this error (UnboundLocalError: local variable 'cursor' referenced before assignment)
After hours of playing with the code and research I need your help.
This is my file, please let me know if theres anything else I need to share.
thank you
from flask import Flask, render_template, json, request
from flask.ext.mysqldb import MySQL
from werkzeug import generate_password_hash, check_password_hash
app = Flask(__name__)
mysql = MySQL()
app.config['MYSQL_DATABASE_USER'] = 'x'
app.config['MYSQL_DATABASE_PASSWORD'] = 'x'
app.config['MYSQL_DATABASE_DB'] = 'x'
app.config['MYSQL_DATABASE_HOST'] = 'x'
mysql.init_app(app)
#app.route('/')
def main():
return render_template('index.html')
#app.route('/login')
def login():
return render_template('login.html')
#app.route('/showSignUp')
def showSignUp():
return render_template('signup.html')
#app.route('/signUp',methods=['POST','GET'])
def signUp():
try:
_name = request.form['inputName']
_email = request.form['inputEmail']
_password = request.form['inputPassword']
# validate the received values
if _name and _email and _password:
# All Good, let's call the MySQL
conn = mysql.connect()
cursor = conn.cursor()
_hashed_password = generate_password_hash(_password)
cursor.callproc('sp_createUser',(_name,_email,_hashed_password))
data = cursor.fetchall()
if len(data) is 0:
conn.commit()
return json.dumps({'message':'User created successfully !'})
else:
return json.dumps({'error':str(data[0])})
else:
return json.dumps({'html':'<span>Enter the required fields</span>'})
except Exception as e:
return json.dumps({'error':str(e)})
finally:
cursor.close()
conn.close()
if __name__ == '__main__':
app.run()
You only define conn and cursor inside the if block checking the form values. If the block is not entered, they're not defined, but you still try to reference them to close them anyway. You should only call close on both if you've defined them. Either move conn = and cursor = to before the if block, or move the close calls to within the block.
However, the bigger problem is that you're misunderstanding/overcomplicating how to use Flask-MySQLdb. It will automatically create the connection and close it when the request is done, which also closes the cursor. Simply use the extension as described in the docs.
...
cur = mysql.connection.cursor()
cur.callproc('sp_createUser', (name, email, hashed_password))
data = cur.fetchall()
...
Personally I would recommend using a context manager to handle opening and closing of your cursor and connection. You can achieve this fairly simply and it is cleaner and easier to debug. This also would eliminate the problem of trying to close a connection or cursor before it is opened in your giant try except block.
from contextlib import closing
# do a bunch of stuff prior to opening connection
with closing(mysql.connect()) as conn:
with closing(conn.cursor()) as cursor:
# do a bunch of stuff and don't worry about running .close()
You can view the docs for closing here.
Using the closing would change your code to be something like this. Although it could use more refactoring, but that is a question for the code review site.
from flask import Flask, render_template, json, request
from flask.ext.mysqldb import MySQL
from werkzeug import generate_password_hash, check_password_hash
from contextlib import closing
app = Flask(__name__)
mysql = MySQL()
app.config['MYSQL_DATABASE_USER'] = 'x'
app.config['MYSQL_DATABASE_PASSWORD'] = 'x'
app.config['MYSQL_DATABASE_DB'] = 'x'
app.config['MYSQL_DATABASE_HOST'] = 'x'
mysql.init_app(app)
#app.route('/')
def main():
return render_template('index.html')
#app.route('/login')
def login():
return render_template('login.html')
#app.route('/showSignUp')
def showSignUp():
return render_template('signup.html')
#app.route('/signUp',methods=['POST','GET'])
def signUp():
try:
_name = request.form['inputName']
_email = request.form['inputEmail']
_password = request.form['inputPassword']
# validate the received values
if _name and _email and _password:
# All Good, let's call the MySQL
with closing(mysql.connect()) as conn:
with closing(conn.cursor()) as cursor:
_hashed_password = generate_password_hash(_password)
cursor.callproc('sp_createUser',(_name,_email,_hashed_password))
data = cursor.fetchall()
if len(data) is 0:
conn.commit()
return json.dumps({'message':'User created successfully !'})
else:
return json.dumps({'error':str(data[0])})
else:
return json.dumps({'html':'<span>Enter the required fields</span>'})
except Exception as e:
return json.dumps({'error':str(e)})
if __name__ == '__main__':
app.run()

Categories

Resources