-2

I am trying to add data to my mysql database with a HTTP post request, but in the way it's set up now, if we post more than once, the data from the first post gets changed to 0 because I declare all the variables in the same definition. How can I fix this?

I have tried to declare a global variable in a second def, but it just loops that def instead of the one I have now.

#!/usr/bin/env python

import pymysql.cursors
from flask import Flask, request
from Crypto.Cipher import AES

connection = pymysql.connect('localhost','esp', 'password', 'points')
app = Flask(__name__)

@app.route('/post', methods = ["POST"])


def post():

    hits1 = 0
    hits2 = 0
    punch1 = 0
    punch2 = 0
    kick1 = 0
    kick2 = 0
    takedown1 = 0
    takedown2 = 0

    print(request.data)
    cipher = AES.new("abcdefghijklmnop")

    decryptedData = cipher.decrypt(request.data)


    data = decryptedData.decode("utf-8")
    print(data)

    print(data)
    if(data[:1]=="e"):
        if(data[1:2] == "1"):
            hits1+=1
            print(hits1)

    if (data[:1]=="1"):
        if(data[1:2]=="1"):
            punch1+=1
        elif(data[1:2]=="2"):
            kick1+=1
        elif(data[1:2]=="3"):
            takedown1+=1
    elif(data[:1]=="2"):
        if(data[1:2]=="1"):
            punch2+=1
        elif(data[1:2]=="2"):
            kick2+=1
        elif(data[1:2]=="3"):
            takedown2+=1
    points1 = punch1 + kick1 * 2 + takedown1 * 3
    points2 = punch2 + kick2 * 2 + takedown2 * 3
    print(points1)
    print(points2)

    try:
       with connection.cursor() as cursor:


            cursor.execute("INSERT INTO points values({0}, {1}, {2}, {3}, {4}, {5})".format(1, hits1, kick1, punch1, takedown1, points1))
            cursor.execute ("INSERT INTO points values({0}, {1}, {2}, {3}, {4}, {5})".format(2, hits2, kick2, punch2, takedown2, points2))


            connection.commit()
            print ("Data committed")
            return 'ok'
    except:
       connection.close()
app.run(host='0.0.0.0', port= 8090)

The value of the previous post gets changed to 0, but i want to keep that value

roganjosh
  • 12,594
  • 4
  • 29
  • 46

1 Answers1

0

It seems that you want to keep the variables you define at the top of your function (hits1, hits2...). The problem, as you stated, is that these variables are redefined every time your function is called.

The simplest way to do that (though a questionable design) is to use global variables. To define a global variable, you could do this:

hits1 = 0
hits2 = 0
# ...

@app.route('/post', methods = ["POST"])
def post():
    global hits1, hits2

    # ...

That way, the values will be kept between requests. A way that I (personnally) prefer, though it's still the same idea, is to keep your data in a "Storage" class:

class Storage:
    hits1 = 0
    hits2 = 0
    # ...

@app.route('/post', methods = ["POST"])
def post():
    # Instead of just using hits1, hits2, ...
    # We now use Storage.hits1, ...
    # Example:

    # ...

    Storage.points1 = Storage.punch1 + Storage.kick1 * 2 + Storage.takedown1 * 3

    # ...

That works. But of course, this is forgotten every time you restart your Flask application. If you want actual persistence (which is what you're trying to achieve, as you're using a database), is something that would query the database (potentially with a cache in order to limit the number of queries) every time a user makes a request to your server:

class Database:
    def __init__(self):
        # Connect to your database
        self._hits1 = None

    @property
    def hits1(self):
        if self._hits1 is None:
            # self._hits1 = (Load data from the database)

        return self._hits1

    # ...

database = Database()

@app.route('/post', methods = ["POST"])
def post():
    # Loads from the database
    hits1 = database.hits1

    # ...

    # In this case, you'd probably want to move your INSERT query to your database class

A few comments: if you want to keep your values between requests, it's probably that you want to UPDATE your database instead of INSERTing data (but that's just my interpretation of your code).

Also, using an_sql_request.format(data) is a very bad practice, as it can help potential SQL injections. Most database drivers offer a way of preparing queries. For example with mysql.connector:

cur = connection.cursor()
sql = "INSERT INTO MyTable (Col1, Col2) VALUES (%s, %s)"
cur.execute(sql, (value_for_col1, value_for_col2))
Thomas Kowalski
  • 1,995
  • 4
  • 20
  • 42