mysql update current data - mysql

I'd like to increase/decrease upVote column value by 1 depending on isUpVote boolean value. I get this error when I try the code below. postID and upVote values are all integer.
MySQLdb._exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'upVote': 0}' - 1 WHERE postID = '2'' at line 1")
#app.route('/posts/upvote', methods=['GET', 'PATCH'])
def upvote_post():
if request.method == 'PATCH':
data = request.get_json()
print(data)
postID = data['postID']
isUpVote = data['isUpVote']
cur = mysql.connection.cursor()
cur.execute("SELECT upVote FROM posts WHERE postID = '{}'".format(postID))
current_upVote = cur.fetchone()
if isUpVote:
cur.execute("UPDATE posts SET upVote = '{0}' + 1 WHERE postID = '{1}'".format(current_upVote, postID))
else:
cur.execute("UPDATE posts SET upVote = '{0}' - 1 WHERE postID = '{1}'".format(current_upVote, postID))
How should I fix the error?
And I'd like to know if there's a simpler way to update the upVote value in one line without defining current_upVote variable.

You don't need the select Query at all, you can simple add or subtract 1 of the current value
#app.route('/posts/upvote', methods=['GET', 'PATCH'])
def upvote_post():
if request.method == 'PATCH':
data = request.get_json()
print(data)
postID = data['postID']
isUpVote = data['isUpVote']
cur = mysql.connection.cursor()
if isUpVote:
cur.execute("UPDATE posts SET upVote = upVote + 1 WHERE postID = '{0}'".format( postID))
else:
cur.execute("UPDATE posts SET upVote = upVote - 1 WHERE postID = '{0}'".format( postID))

current_upvote is a dictionary containing the row that you fetched. You need to extract the value from it.
You can also do the arithmetic in Python, then just do a single query to update.
You should use parameters rather than string formatting to substitute into queries.
cur.execute("SELECT upVote FROM posts WHERE postID = %s", (postID,))
current_upVote = cur.fetchone()
if isUpvote:
vote = current_upVote['upVote'] + 1
else:
vote = current_upVote['upVote'] - 1
cur.execute("UPDATE posts SET upVote = %s WHERE postID = %s", (vote, postID))
However, the best way to do it is nbk's answer. I only posted this to explain why your code didn't work, and also to show the proper use of parameters.

Related

Python3 compare data from DB and write the answer back to DB

[Introduction]
I am currently creating a web application in Python 3.7.4 over CGI. (the web server does not support wsgi)
The application is a simple survey were users answer questions into a carousel form.
Answers are written in the DB (MySql) according to the respondentID.
No problems until now. Everything is working fine.
However, I have been asked to insert a logic into the survey and display results according to it.
[Objective]
Lets say I have 30 questions and users can answer 0, 1 or 2 for each of them.
Answers are processed only when the user complete the survey.
At completion, data are stored as integer inside DB as si001, si002, si003,....si030
If there are values inside the DB, I would like to count how many of each possible answer have been recorded. For example, how many 0s, how many 1s, how many 2s.
The results will be recorded inside the DB in different columns. (simaru, sisankaku, sibatsu)
What I would like to do is something similar to the code below. (code is obviously wrong)
I know the SELECT status from the DB can be summarized in one cursor.execute only, but for the time being (logic details are yet to be completed) I would like to left it as it is.
[CODE]
#app.route('/results1', methods=['GET', 'POST'])
def results1():
# Check survey completion status
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT * FROM private_survey WHERE privateid = %s', (session['username'],))
account = cursor.fetchone()
if account['surveystatus'] == 'Available' or account['surveystatus'] == 'Started':
# Check survey status, if available redirect to noresults
return redirect(url_for('noresults'))
else:
# Survey already completed, show results1
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT si001, si002, si003, si004, si005, si006, si007, si008, si009, si010, si011, si012, si013, si014, si015, si016, si017, si018, si019, si020, si021, si022, si023, si024, si025, si026, si027, si028, si029, si030 FROM private_survey INNER JOIN private_survey_answers ON private_survey.surveyid=private_survey_answers.surveyid WHERE private_survey.privateid=%s', (session['username'],))
answer1 = cursor.fetchone()
maru = 0
sankaku = 0
batsu = 0
simaru = 0
sisankaku = 0
sibatsu = 0
for x in answer1:
if x == 2:
simaru = maru + 1
if x == 1:
sisankaku = sankaku + 1
if x == 0:
sibatsu = batsu + 1
cursor.execute('UPDATE private_survey_answers INNER JOIN private_survey ON private_survey.surveyid=private_survey_answers.surveyid SET simaru = %s, sisankaku = %s, sibatsu = %s WHERE private_survey.privateid = %s', (simaru, sisankaku, sibatsu, session['username'],))
mysql.connection.commit()
return render_template('results1.html', answer1=answer1, account=account)
Any help or idea would be very appreciated.
I solved the problem using the count function.
The solution I found is both able to display the count in real time and write it in the DB for CSV download, etc..
#app.route('/results1', methods=['GET', 'POST'])
def results1():
# Check survey completion status
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT * FROM private_survey WHERE privateid = %s', (session['username'],))
account = cursor.fetchone()
if account['surveystatus'] == 'Available' or account['surveystatus'] == '開始':
# Check survey status, if available redirect to noresults
return redirect(url_for('noresults'))
else:
# Survey already completed, show results1
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT si001, si002, si003, si004, si005, si006, si007, si008, si009, si010, si011, si012, si013, si014, si015, si016, si017, si018, si019, si020, si021, si022, si023, si024, si025, si026, si027, si028, si029, si030 FROM private_survey INNER JOIN private_survey_answers ON private_survey.surveyid=private_survey_answers.surveyid WHERE private_survey.privateid=%s', (session['username'],))
answer1 = cursor.fetchone()
cnt = [answer1['si001'], answer1['si002'], answer1['si003'], answer1['si004'], answer1['si005']]
cnt.count(2)
cnt.count(1)
cnt.count(0)
cursor.execute('UPDATE private_survey_answers INNER JOIN private_survey ON private_survey.surveyid=private_survey_answers.surveyid SET simaru = %s, sisankaku = %s, sibatsu = %s WHERE private_survey.privateid = %s', (cnt.count(2), cnt.count(1), cnt.count(0), session['username'],))
mysql.connection.commit()
return render_template('results1.html', answer1=answer1, account=account, cnt=cnt)

(Python, MySQL) How can I assign a variable to a MySQL query?

I have a piece of code like this:
isbn = 4567
c.execute("SELECT * FROM book WHERE Book_d = %s;",(isbn,))
search = c.fetchone()
print(search)
But I want to change the attribute to a variable like this:
isbn = 4567
bisbn = 'Book_d'
c.execute("SELECT * FROM book WHERE %s = %s;",(bisbn, isbn,))
search = c.fetchone()
print(search)
But I guess the syntax is wrong here.
I just wanted to ask whether it is possible to do something like this and if so how?
Thanks
Please check this.
isbn = 4567
bisbn = 'Book_d'
sql_query = "SELECT * FROM book WHERE %s = %s;"%(bisbn, isbn,)
Or if you are using python3
sql_query = f"SELECT * FROM book WHERE {bisbn} = {isbn}"
print(sql_query)

update column a values to column b corresponding to particular id in python

I have written a code to read 2 columns(raw_id, notes) from mysql db using pymysql, which gives me list of dictionary. Now I want to extract id values, store it and update review column with notes column values for every raw_id at the record level. Can anybody help me with this.
db_data contains:
[OrderedDict([(u'raw_id', u'52c00'), (u'notes', u'awesome')]),
OrderedDict([(u'raw_id', u'54df0'), (u'notes', u'loved it')]),
OrderedDict([(u'raw_id', u'5cd00'), (u'notes', u'enjoyed')]),...]
Code I've used:
for row in db_data:
text = row.values()
r_id = text[0]
update_sql = "update raw_data set review = notes where
customer_id = {0} and raw_id = {1}"
res = sql_db.execute_write(update_sql, [inp_cust_id, r_id])
print res
Error I'm getting:
TypeError: not all arguments converted during string formatting
for row in db_data:
text = str(row.values())
r_id = str(text[0])
update_sql = "update raw_data set review = notes where
customer_id = {0} and raw_id = {1}"
res = sql_db.execute_write(update_sql, [inp_cust_id, r_id])
print res
try this

SQL Statement to update multiple columns with multiple where conditions

So I have the following SQL statement:
db.exec("UPDATE products SET product_description = '#{fj_description}' AND personalization = '#{fj_personalization}' AND product_photo = '#{fj_product_photo}' AND order_information = '#{fj_order_information}' WHERE campaign_name = '#{camp_name}' AND product_type = 'fleecejacket'")
All of the variables are returning the correct text that's retrieved from an HTML input field, so it seems to be something wrong with the sql statement. When I try to update the database, I get this error:
PG::InvalidTextRepresentation at /update_products
ERROR: invalid input syntax for type boolean: "soft, midweight fleece" LINE 1: UPDATE products SET product_description = 'soft, midweight f... ^
Try using comma instead AND:
"UPDATE products
SET product_description = '#{fj_description}',
personalization = '#{fj_personalization}',
product_photo = '#{fj_product_photo}',
order_information = '#{fj_order_information}'
WHERE campaign_name = '#{camp_name}'
AND product_type = 'fleecejacket'"

Rails 3. Checking for true values in SQL

I need to check if the column exam has a value of true. So I set this up but it doesn't work...
#exam_shipments = Shipment.where("exam <> NULL AND exam <> 0 AND customer_id = ?", current_admin_user.customer_id)
# This one gives me error "SQLite3::SQLException: no such column: true:"
#exam_shipments = Shipment.where("exam = true AND customer_id = ?", current_admin_user.customer_id)
#exam_shipments = Shipment.where("exam = 1 AND customer_id = ?", current_admin_user.customer_id)
You should really just stick to AR syntax:
#exam_shipments = Shipment.where(:exam => true, :customer_id => current_admin_user.customer_id)
Assuming :exam is a boolean field on your Shipment model. ActiveRecord takes care of converting your query to the proper syntax for the given database. So the less inline SQL you write, the more database-agnostic and portable your code will be.
Why do you need do execute SQL?
It's much easier just to do
#exam_shipments = Shipment.find_by_id(current_admin_user.customer_id).exam?