Not inserting rows in mysql with flask application but autoincrements id

Question:

I am learning how to create a flask application that insert records un a mysql database whose values are obtained from an html form.

I have written the following piece of code:

from flask import Flask, render_template, request, redirect, url_for, flash
from flask_mysqldb import MySQL

app = Flask(__name__)

#MySql Connection
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = 'password'
app.config['MYSQL_DB'] = 'flaskcontacts'
mysql = MySQL(app)

# settings
app.secret_key = 'mysecretkey'

@app.route('/')
def Index():
    return render_template('index.html')

@app.route('/add_contact', methods=['POST'])
def add_contact():
    if request.method == 'POST':
        fullname = str(request.form['fullname'])
        phone = str(request.form['phone'])
        email = str(request.form['email'])
        cur = mysql.connect.cursor()
        print(str(fullname), phone, email)
        cur.execute("INSERT INTO flaskcontacts.contacts (fullname, phone, email) VALUES (%s, %s, %s)",
        (fullname, phone, email))

        mysql.connection.commit()
        flash('Contact Added successfully')

        return redirect(url_for('Index'))

Once I execute it I see that I obtain the message “Contact added succesfully” but I cannot see any record in the mysql database, however I see that the Id that is autoincremental, it is incremented. So if I update the table directly into the database it works and shows me a number of Id that was already autoincremented, as if the previous piece of code worked but it doesn’t update it at all.

I have invested many hours trying to fix this problem, but apart from the answer I would appreciate if you can help me with some best practices of how to debug these type of problems.

Regards

Asked By: agm

||

Answers:

MySQL will generate an auto-increment ID before it tries the INSERT. But the INSERT might fail, for example if the INSERT causes a constraint conflict, there will be no row created.

The auto-increment ID can’t be “un-allocated” or otherwise pushed back into a collection of ID values to be handed out. Some other concurrent session might have allocated the next value already, and MySQL does not maintain a pool of ID values, it only knows about the latest value allocated per table.

So MySQL would have to wait until the INSERT had succeeded (including checking all constraints, executing any triggers, etc.), while blocking any other concurrent sessions from doing their INSERTs. Only then could it reliably allocate ID’s without “wasting” any values.

That proved to be too constraining on parallelism for MySQL, so their compromise is to quickly allocate an ID, then unlock the auto-increment mechanism for that table, and allow concurrent sessions to proceed. THEN attempt the INSERT using the ID generated. This allows for greater throughput.

Your app prints “Contact Added successfully” even if the INSERT resulted in an error. You don’t check for any error in the code you show above, so how do you know it was successful?

Anyway, you shouldn’t worry about “wasted” ID values. They are not intended to be consecutive, only unique. If you feel you might run out of integers, then do the math. What is the maximum value of your integer column? What is the rate of generating new values? Based on these, you should be able to figure out how long you’ve got before you run out. This shouldn’t be difficult for a software developer to do this simple math.

Answered By: Bill Karwin

The problem was here in this line:

cur = mysql.connect.cursor()

That is inside the function add_contact.

The correct function to use is:

cur = mysql.connection.cursor()

So it was connection instead of connect.

Answered By: agm

you have to use db.commit() to save changes Otherwise your id incremented but nothing is showing in the database

Answered By: Raj Mittal
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.