I have one page HTML with few submit buttons with different names and values. I have all the names of the buttons in one db in SQL. When the user enter in the page usually he click just in one button each time and the form is submitted. How can I loop through this buttons in my flask/python program?
connection = sqlite3.connect('world.db')
cursor = connection.cursor()
sqlite_select_query = """SELECT name FROM countries"""
cursor.execute(sqlite_select_query)
records = cursor.fetchall()
for row in records:
wish = request.form[row[0]]
try:
db.execute("INSERT INTO userinput (user_id, wish, country_name) VALUES (?, ?, ?)", user_id, wish, row[0])
except ValueError:
db.execute("UPDATE userinput SET wish = ? WHERE user_id =? AND country_name=?", wish, user_id, row[0] )
except:
pass
I have one error 400 Bad request.
Ps.: I already tried to put the value of row between ' and ". Doesn't changed anything.
If I put my request.form inside the try session, it just pass.
I put before few "prints" to see where is the error and see that is in the request form.
If I put the name direct in request form and outside the loop for example ‘’’ request.form[“Brazil”]’’’ I can insert in the database with no problems.
Thanks.
I am pretty sure request.form does not contain all countries, just the one associatted button is clicked. You could look at server logs, probably you see info about missing key in request.form. So what you want to is find that specific one:
wish = request.form.get(row[0])
if wish is None:
continue
Related
// SELECT
myDatabaseCursor.execute("SELECT username, password FROM member")
myDatabase.commit()
// get data from form to make a tuple
userCheck = (request.form["signInUsername"], request.form["signInPassword"])
// iterate selected data tuple into a list
results = []
for selectedData in myDatabaseCursor:
results.append(selectedData)
// check if there is a match in MySQL database
if userCheck in results:
session["status"]="logged"
session["user_name"]=request.form["signInUsername"]
return redirect("/member")
else:
return redirect("/error/?message=wrong username or password")
When I ran my server and tried typing in the username and the right password, successfully logged in; tried typing in the username and the wrong password, which, didn't have any match in the database, got rejected logging in. ALL GOOD...
BUT, when I tried typing in the username and the wrong password, which, HAS A MATCH IN THE PASSWORD COLUMN THOUGH DOESN'T BELONG TO THE RIGHT USERNAME, still successfully logged in.
I am really confused now, hope you guys have any idea about this situation.
Thanks, appreciate your replies.
You could change your query to support WHERE clause. Something along the lines of:
# get data from form to make a tuple
username, password = (
request.form["signInUsername"],
request.form["signInPassword"]
)
# SELECT
myDatabaseCursor.execute(
"""
SELECT username, password
FROM member
WHERE username = '{username}' AND password = '{password}'
""".format(username=username, password=password)
)
myDatabase.commit()
# set userCheck to True or False if the myDatabaseCursor result is not empty..
# TODO
# if row was in returned table
if userCheck:
session["status"]="logged"
session["user_name"]=request.form["signInUsername"]
return redirect("/member")
else:
return redirect("/error/?message=wrong username or password")
Probably the problem lies in the session['status']. You never set it to e.g. "unlogged", so if you don't close the browser, the status will always be 'logged' after first successful login.
Try to initialize your variable at the beginning of the script, i.e. session["status"]=None and then in every other page check that the status is actually 'Logged' as you're probably already doing.
session["status"]=None
// SELECT
myDatabaseCursor.execute("SELECT username, password FROM member")
myDatabase.commit()
// get data from form to make a tuple
userCheck = (request.form["signInUsername"], request.form["signInPassword"])
// iterate selected data tuple into a list
results = []
for selectedData in myDatabaseCursor:
results.append(selectedData)
// check if there is a match in MySQL database
if userCheck in results:
session["status"]="logged"
session["user_name"]=request.form["signInUsername"]
return redirect("/member")
else:
return redirect("/error/?message=wrong username or password")
In any case, for the sake of best practice, you should amend your code to apply the logic depicted by #matthewking, retrieving just the password you need to check.
I want to save an API response, on some table of my database, I'm using Postgres along with psycopg2.
This is my code:
import json
import requests
import psycopg2
def my_func():
response = requests.get("https://path/to/api/")
data = response.json()
while data['next'] is not None:
response = requests.get(data['next'])
data = response.json()
for item in data['results']:
try:
connection = psycopg2.connect(user="user",
password="user",
host="127.0.0.1",
port="5432",
database="mydb")
cursor = connection.cursor()
postgres_insert_query = """ INSERT INTO table_items (NAME VALUES (%s)"""
record_to_insert = print(item['name'])
cursor.execute(postgres_insert_query, record_to_insert)
connection.commit()
count = cursor.rowcount
print (count, "success")
except (Exception, psycopg2.Error) as error :
if(connection):
print("error", error)
finally:
if(connection):
cursor.close()
connection.close()
my_func()
I mean, I just wanted to sort of "print" all the resulting data from my request into the db, is there a way to accomplish this?
I'm a bit confused as You can see, I mean, what could be some "print" equivalent to achieve this?
I mean, I just want to save from the API response, the name field, into the database table. Or actually INSERT that, I guess psycopg2 has some sort of function for this circumstance?
Any example You could provide?
EDIT
Sorry, I forgot, if I run this code it will throw this:
PostgreSQL connection is closed
A particular name
Failed to insert record into table_items table syntax error at or near "VALUES"
LINE 1: INSERT INTO table_items (NAME VALUES (%s)
There are a few issues here. I'm not sure what the API is or what it is returning, but I will make some assumptions and suggestions based on those.
There is a syntax error in your query, it is missing a ) it should be:
postgres_insert_query = 'INSERT INTO table_items (NAME) VALUES (%s)'
(I'm also assuming thatNAME` is a real column in your database).
Even with this correction, you will have a problem since:
record_to_insert = print(item['name']) will set record_to_insert to None. The return value of the print function is always None. The line should instead be:
record_to_insert = item['name']
(assuming the key name in the dict item is actually the field you're looking for)
I believe calls to execute must pass replacements as a tuple so the line: cursor.execute(postgres_insert_query, record_to_insert) should be:
cursor.execute(postgres_insert_query, (record_to_insert,))
When adding a vital component of methods=["POST", "GET"], my code gives the error:
Line 127, in PatientDashboard
""".format(Data[0][0]))
IndexError: list index out of range
I understand what this error normally means but I don't understand how adding methods affect the size of my list.
#app.route("/PatientDashboard.html", methods=["GET", "POST"])
def PatientDashboard():
Username = (request.args.get("Username"))
Connection = sqlite3.connect(DB)
Cursor = Connection.cursor()
Data = Cursor.execute("""
SELECT *
FROM PatientTable
WHERE Username = '{}'
""".format(Username))
Data = Data.fetchall()
AllAppointments = Cursor.execute("""
SELECT Title, Firstname, Surname, TimeSlot, Date, Status
FROM AppointmentTable
INNER JOIN DoctorTable ON AppointmentTable.DoctorID = DoctorTable.DoctorID
WHERE PatientID = '{}'
""".format(Data[0][0]))
AllAppointments = AllAppointments.fetchall()
The SQL statements work perfectly (database isn't empty) and when adding print(Data) after the first SQL statement there is an output of a nested list.
I have tried troubleshooting by looking at various other questions on stackoverflow but with no luck.
Thank you ever so much in advance.
EDIT 1:
Username = (request.args.get("Username"))
print("Username: ", Username)
Gives the correct output, e.g. Username: nx_prv but after using the POST request the output becomes Username: None.
EDIT 2:
I have managed to fix this using flask.sessions. The problem was that the request.args.get("Username") was getting 'reset' every time.
The scenario I envision: the route was tested with a GET method (because there was not methods argument), and everything was fine. The methods argument was added so a POST could be tested, and it "stopped working". But it really didn't stop working, it's just not built to handle a POST request.
From flask doc on request object the two salient attributes are:
form
A MultiDict with the parsed form data from POST or PUT requests. Please keep in mind that file uploads will not end up here, but
instead in the files attribute.
args
A MultiDict with the parsed contents of the query string. (The part in the URL after the question mark).
So a GET request will "populate" args and a POST request, form. Username will be None from this line Username = (request.args.get("Username")) on a POST request.
You can determine which method by interrogating the method attribute of the request object.
method
The current request method (POST, GET etc.)
I'm working o a shopping cart with python and flask. I want that when a user clicks on the order button on an item, they are redirected to /cart/add/ route where SQL statement is run to retrieve data such as username from users table, item name and price from allfood table based on the items id passed in the URL and address from delivery_address table. once this info is collected it will also be added to the shopping_cart table where it will be kept temporarily until i figure out the next step. I'm having trouble with the SQL and I was hoping someone could correct it because it's giving me an error.
"INSERT INTO shopping_cart_tbl VALUES (username, address, item, cost) \
SELECT user.username, addr.address, food.item_, food.cost \
FROM register_tbl AS user FULL JOIN delivery_addresses_tbl AS addr FULL JOIN allfood_tbl AS food \
ON user.username = addr.username AND food.id=%s"
for the sake of knowing if I can improve my code with any suggestions, I'll post the code for the route
#app.route('/cart/add/<item_id>', methods=['POST', 'GET'])
def sadd_to_cart(item_id):
# do a cross join of the three tables maybe to retrieve the necessarinformation
if 'userkey' in session:
con = pymysql.connect("localhost", "root", "", "sampledb")
cursor_full_join = con.cursor()
sql="INSERT INTO shopping_cart_tbl VALUES (username, address, item, cost) \
SELECT user.username, addr.address, food.item_, food.cost \
FROM register_tbl AS user FULL JOIN delivery_addresses_tbl AS addr FULL JOIN allfood_tbl AS food \
ON user.username = addr.username AND food.id=%s"
cursor_full_join.execute(sql, item_id)
return render_template('homepage.html')
elif 'userkey' not in session:
return redirect('/login')
else:
return redirect('/login')
I appreciate the help.
edit: i removed unnecessary quotation marks. Sorry. i hadn't noticed them for some reason
I am creating a simple app in pyramid . While inserting data i am getting db locked error.
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) database is locked [SQL: 'INSERT INTO users (name, email, number) VALUES (?, ?, ?)'] [parameters: ('test', 't#t.com', '123654')]
But first time it inserts the data correctly and on 2nd time it gives this error.
Any idea why this is happening second time ?
Here is my code :
name = request.params['name']
email = request.params['email']
no = request.params['number']
DBSession.add(User(name, email, no))
# Get the new ID and redirect
users = DBSession.query(User).all()
SQLite can only handle 1 concurrent transaction.
Have you tried commit()before performing a query() then close() to end the session?
name = request.params['name']
email = request.params['email']
no = request.params['number']
DBSession.add(User(name, email, no))
# Commit the transaction if complete
DBSession.commit()
# Get the new ID and redirect
users = DBSession.query(User).all()
# Close the session
DBSession.close()