Uploading HTML form data to MySQL database using Flask - python

I am sending data from an HTML post to a Python Flask function submit() which then connects and sends it to a MySQL database, which I am managing from BlueHost's phpMyAdmin. It isn't working, however.
Here is my HTML form:
<form method="POST">
<label>Coordinates:</label>
<input type="text" name="coords"> <!-- COORDS -->
<br/><br/>
<label>Year:</label>
<input type="text" name="year"> <!-- YEAR -->
<br/><br/>
<label>Range</label>
<select name="range"> <!-- RANGE -->
<option value="one">1700s or earlier</option>
<option value="two">early 1800s</option>
<option value="three">mid 1800s</option>
<option value="four">late 1800s</option>
<option value="five">1900s</option>
<option value="six">1910s</option>
<option value="seven">1920s</option>
<option value="eight">1930s</option>
</select>
<br/><br/>
<label>Photo:</label>
<input type="file" name="photo" accept="image/png, image/jpeg"> <!-- PHOTO -->
<br/><br/>
<label>Caption:</label>
<input type="text" name="caption"> <!-- CAPTION -->
<br/><br/>
<label>Source:</label>
<input type="text" name="source"> <!-- SOURCE -->
<br/><br/>
<div style="display:flex; justify-content:center;">
<button>Submit</button>
</div>
</form>
Here is my Python Flask file (should take the form data upon submission, connect to the database, and insert data):
from flask import Flask, render_template, request
import mysql.connector
from werkzeug.utils import secure_filename #input validation for files
from datetime import datetime
import os
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/submit', methods=['POST'])
def submit():
# get the form data from the request
coords = request.form['coords']
year = request.form['year']
range = request.form['range']
photo = request.files['photo']
caption = request.form['caption']
source = request.form['source']
# save the photo to the file manager
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
filename = secure_filename(f"{timestamp}_{photo.filename}")
photo.save(os.path.join('/home3/genealu6/public_html/openmemorymap/photos/', filename))
# connect to the database
cnx = mysql.connector.connect(user='genealu6_hamaharoof', password='[REDACTED]',
host='localhost', database='genealu6_markers')
cursor = cnx.cursor()
# insert the form data into the database
query = ("INSERT INTO contacts (coordinates, year, yearrange, photo, caption, source) "
"VALUES (%s, %s, %s, %s, %s, %s)")
data = (coords, year, range, filename, caption, source)
cursor.execute(query, data)
cnx.commit()
# close the database connection
cursor.close()
cnx.close()
return 'Data submitted successfully'
I'm not sure where the issue could be. My username, password, hostname, and database name, to connect to MySQL, are all correct.
Note that I am also trying to upload the file uploaded in the form to a folder in the BlueHost file manager which is not working:
photo.save(os.path.join('/home3/genealu6/public_html/openmemorymap/photos/', filename))

A potential issue here can be a missing port number. Try using 3306 (default port) in your connect statement.

Related

HTML form data not updating in postgres Table throug flask python

Hi i am trying to upload create.html fields data to postgres DB.
My html form code is as below:
<!DOCTYPE html>
{% block content %}
<h1>{% block title %} Add a New Book {% endblock %}</h1>
<form method="post">
<p>
<label for="title">Title</label>
<input type="text" name="title"
placeholder="Book title">
</input>
</p>
<p>
<label for="author">Author</label>
<input type="text" name="author"
placeholder="Book author">
</input>
</p>
<p>
<label for="pages_num">Number of pages</label>
<input type="number" name="pages_num"
placeholder="Number of pages">
</input>
</p>
<p>
<label for="review">Review</label>
<br>
<textarea name="review"
placeholder="Review"
rows="15"
cols="60"
></textarea>
</p>
<p>
<button type="submit">Submit</button>
</p>
</form>
{% endblock %}
Once i enter values in form those values should reflect in my postgres in below DB table
CREATE TABLE sample_schema.books (
id serial PRIMARY KEY,
title text COLLATE pg_catalog."default" NOT NULL,
author text COLLATE pg_catalog."default" NOT NULL,
pages_num integer NOT NULL,
review text COLLATE pg_catalog."default",
date_added date DEFAULT CURRENT_TIMESTAMP
)
and my python code is as follows
import os
import psycopg2
from flask import Flask, render_template
app = Flask(__name__)
def get_db_connection():
conn = psycopg2.connect(user="user",
password="pass123",
host="00.00.0.00",
port="5432",
database="samp_DB")
return conn
from flask import Flask, render_template, request, url_for, redirect
#app.route('/create/', methods=('GET', 'POST'))
def create():
if request.method == 'POST':
title = request.form['title']
author = request.form['author']
pages_num = int(request.form['pages_num'])
review = request.form['review']
conn = get_db_connection()
cur = conn.cursor()
cur.execute('INSERT INTO sample_schema.books (title, author, pages_num, review)'
'VALUES (%s, %s, %s, %s)',
(title, author, pages_num, review))
conn.commit()
cur.close()
conn.close()
return redirect(url_for('index'))
return render_template('D:/create.html')
Once after i ran above code and enter values in html form the fields that i entered in form doesn't updating in book table.
Thanks in advance

MySQL data is not showing when data entered using HTML form in python

This is the Python code for a flask application :
from flask import Flask, render_template, request
from sqlalchemy import create_engine
import pymysql
db = create_engine("mysql+pymysql://root:password#localhost:3306/database")
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/success", methods=["POST"])
def success():
name = request.form.get("name")
email = request.form.get("username")
password = request.form.get("password")
rpassword = request.form.get("rpassword")
db.execute("INSERT INTO information(name, email, password, rpassword)
VALUES(name, email, password, rpassword)",
{'name':name, 'email':email, 'password':password,
'rpassword':rpassword})
return render_template("success.html", name=name)
This is the HTML Code
<form id="sign" action="{{url_for('success')}}" method="POST">
Name: <input type="text" name="name"><br><br>
Email: <input type="text" name="username"><br><br>
Password: <input type="password" name="password"><br><br>
Confirm-Password:<input type="password" name="rpassword"><br><br>
<input type="Submit" name="submit" value="Sign Up">
</form>
Whenever I try to add data using HTML form i can enter data successfully and success.html also load but the data is not showing in MySQL
Any suggestion ??
Please read the doc.
https://www.python.org/dev/peps/pep-0249/#paramstyle
Probably for keyword arguments you should use:
"INSERT INTO information(name, email, password, rpassword) VALUES(%(name)s, %(email)s, %(password)s, %(rpassword)s)"
You need to commit when it is DML commands .
https://docs.sqlalchemy.org/en/latest/core/connections.html#using-the-threadlocal-execution-strategy
try:
db.execute(...)
db.commit()
except:
db.rollback()

Cannot insert row using Flask and SQLAlchemy

I am doing CS50 project and the current task is to create a register page. User fills in the form and presses button. So it has to be insert into my PostgreSQL database. But when I fill the form and press 'Register' I got this error:
StatementError: (sqlalchemy.exc.InvalidRequestError) A value is required for bind parameter u'surname' [SQL: u'INSERT INTO users (name, surrname, nickname, password) VALUES (%(name)s, %(surname)s,%(nickname)s, %(password)s'] [parameters: [{':password': u'', ':name': u'John', ':surname': u'Young', ':nickname': u'yolojohny1'}]] (Background on this error at: http://sqlalche.me/e/cd3x)
books.py
import os
from flask import Flask, session, render_template, request
from flask_session import Session
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
app = Flask(__name__)
# Check for environment variable
if not os.getenv("DATABASE_URL"):
raise RuntimeError("DATABASE_URL is not set")
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Set up database
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))
#app.route("/")
def index():
return render_template("register.html")
#app.route('/register', methods=["POST"])
def register():
"REGISTRATION PROCESS"
# Get form information
name = request.form.get("name")
surname = request.form.get("surname")
nickname = request.form.get("nickname")
password = request.form.get("password")
db.execute("INSERT INTO users (name, surrname, nickname, password) VALUES (:name, :surname,"
":nickname, :password", {":name": name, ":surname": surname, ":nickname": nickname,
":password": password})
db.commit()
return render_template("success.html")
register.html:
{% extends "layout.html" %}
{% block title %}
New User
{% endblock %}
{% block body %}
<h1>Register new account</h1>
<form action="{{ url_for('register') }}" method="post">
<div class="form-group">
<input class="form-control" name="name" placeholder="First Name">
</div>
<div class="form-group">
<input class="form-control" name="surname" placeholder="Second Name">
</div>
<div class="form-group">
<input class="form-control" name="nickname" placeholder="Nickname">
</div>
<div class="form-group">
<input type="password" class="form-control" name="password" placeholder="Password">
</div>
<div class="formgroup">
<button class="btn btn-primary">Create account!</button>
</div>
</form>
{% endblock %}
database:
CREATE TABLE "users" (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
surrname VARCHAR NOT NULL,
nickname VARCHAR NOT NULL,
password VARCHAR NOT NULL
)
What should I do? I googled this Error but nothing helps.
you are almost there.
db.execute("INSERT INTO users (name, surrname, nickname, password) VALUES (:name, :surname, :nickname, :password", {":name": name, ":surname": surname, ":nickname": nickname, ":password": password})
Firstly, this doesn't execute as you are missing the closing parenthesis after your VALUES list. So to get the statement to execute I had to make it:
db.execute("INSERT INTO users (name, surrname, nickname, password) VALUES (:name, :surname, :nickname, :password)", {":name": name, ":surname": surname, ":nickname": nickname, ":password": password})
I imagine that is just a typo translating info into the questions, but nonetheless.
Now, the colon (:), prior to the parameter names in your SQL statement is there to tell SQLAlchemy that that name is a bound parameter. You can read more about it here.. You don't need to include that in the keys of your parameter values dict, and that is why you are seeing the error. SQLAlchemy is looking for a parameter named surname but that doesn't exist in your supplied parameter values, :surname does, but ':surname' != 'surname' and so no value can be found for the parameter.
This should get you across the line:
db.execute("INSERT INTO users (name, surrname, nickname, password) VALUES (:name, :surname, :nickname, :password)", {"name": name, "surname": surname, "nickname": nickname, "password": password})

how to dynamicaly create table column names and insert values using flask and mysql

I would like to create multiple text boxes based on the value given in a particular text box and another text box which will hold table name now I wanted to fetch the table name from the text box and also get the values given in the multiple text boxes as a column name and should create a database in MySQL.
here is my py
from flask import Flask
from flask import request
from flask import render_template
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'] = 'matrimony'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
#app.route('/')
def index():
return render_template('index1.html')
#app.route('/searchQuery', methods=['POST'])
def search_query():
if request.method: "POST"
conn = mysql.connect()
cursor = conn.cursor()
name=request.form.get('name')
sq_ = request.form.get('searchQuery')
x=request.form.get('x')
cursor.execute("""CREATE TABLE `%s`( NAME VARCHAR(50) DEFAULT NULL) """ % (name))
print(sq_)
return render_template('simplesearch.html', search_query=sq_)
if __name__ == '__main__':
app.run()
index1.html
<form action="{{ url_for('search_query') }}" method="post">
Name:<input type="text" name="name">
Column Number:<input type="text" name="searchQuery" id="searchQuery"><input type="submit" value="Submit">
</form>
simplesearch.html
<table>
{% for x in range(search_query | int) %}
<tr>
<td>
<input type="text" name="i{{ x }}">
<input type="hidden" value="{{ search_query }}">
</td>
</tr>
{% endfor %}
<input type="submit" value="Submit">
</table>
It fetches table name from the tex tbox and only one column is created.
Any help with this would be much grateful Thankyou
I assume you need to create dynamic MySQL tables with user defined fields. You do not need to submit the form twice. Create the dynamic fields using a little help of jQuery. Then handle the values in the controller.
Here is a way you can accomplish this like following. The program requires Flask-MySQL which can be installed using pip install Flask-MySQL.
application.py:
from flask import Flask
from flask import request
from flask import render_template
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'] = 'matrimony'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
#app.route('/')
def index():
return render_template('index1.html')
#app.route('/create_table', methods=['POST'])
def create_table():
if request.method=="POST":
try:
table_name = request.form.get('table_name')
field_name_list = request.form.getlist('fields[]')
field_list = []
for field in field_name_list:
field_list.append(field+ " VARCHAR(50) DEFAULT NULL")
field_query = " ( " + ", ".join(field_list) + " ) "
create_table_query = 'CREATE TABLE `'+table_name+'`' + field_query
conn = mysql.connect()
cursor = conn.cursor()
cursor.execute(create_table_query)
return "Table: "+table_name+" created successfully"
except Exception as e:
return str(e)
if __name__ == '__main__':
app.run(debug = True)
index1.html:
<form action="{{ url_for('create_table') }}" method="post">
Name:<input type="text" name="table_name" id="table_name" />
Column Number:<input type="text" name="number_of_columns" id="number_of_columns" />
<input type="button" id="generate_field_btn" value="Generate Field" />
<div id="dynamic_field">
</div>
<input type="submit" name="Create Table">
</form>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#generate_field_btn").on("click",function(){
$number_of_columns = $("#number_of_columns").val();
$number_of_columns = parseInt($number_of_columns);
for($i=0; $i<$number_of_columns; $i++){
$field_name = "Field "+($i+1)+": ";
$new_element = $field_name+'<input type="text" name="fields[]"/><br/>';
$("#dynamic_field").append($new_element);
}
})
})
</script>
Output:
Getting input fields from user:
Showing success message after table creation:
Ensure the table is created with desired fields from phpMyAdmin:

Get value from URL in another app.route

I have a Flask application that shows text under the URL http://<webroot>/idea/<idea_id>, e.g. http://localhost/idea/123. The idea_id is requested from a database
#app.route("/idea/<idea_id>", methods=["POST","GET"])
def get_idea(idea_id):
db = get_db()
cur = db.execute("select id, title, description, image from ideas where id=?", (idea_id,))
ideas = cur.fetchall()
args = request.path
return render_template("idea.html", ideas=ideas)
In that page I got a file upload:
<form action="{{ url_for("upload_image") }}" method="post" enctype="multipart/form-data">
<p><input type="file" name="image">
<input type=submit value="Hochladen">
</form>
Here's the code that does the upload:
#app.route("/upload_image", methods=["POST", "GET"])
def upload_image():
if not session.get("logged_in"):
abort(401)
image = request.files["image"]
if image and allowed_file(image.filename):
db = get_db()
idea_id = request.view_args["idea_id"]
filename = secure_filename(image.filename)
db.execute("INSERT OR REPLACE INTO ideas (id, image) VALUES (?, ?)", (idea_id, filename))
image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return flash("Bild hochgeladen!")
return redirect(url_for("index"))
I want to insert the path of the image into the database and link it to the ID of the idea (idea_id).
My question is how to get the idea_id-value from used in the URL? I guess I need to URL processors, but I can't wrap my head around the whole process yet.
I would do it as a hidden input in your form.
<form action="{{ url_for("upload_image") }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="idea_id" value="{{ idea_id }}">
<p><input type="file" name="image">
<input type=submit value="Hochladen">
</form>
This would also require modifying your view.
#app.route("/idea/<idea_id>", methods=["POST","GET"])
def get_idea(idea_id):
db = get_db()
cur = db.execute("select id, title, description, image from ideas where id=?", (idea_id,))
ideas = cur.fetchall()
args = request.path
return render_template("idea.html", ideas=ideas, idea_id=idea_id)
This would put idea_id into request.form. You can then access it from upload_image with request.form['idea_id'].

Categories