Forums

Commiting into different tables

So for the last week I have tried and failed to add data into different tables on the same database. Playing with the code today I noticed the error may not be what it seems. My code below has two different classes, used as my tables, and two different pages. It is supposed to have two different pages that will add data into two different tables, simple. I am sure that it is incorrect but my actual problem is that the code is unresponsive. For example, the page '/test' will and always has, added information into the table "comments" which corresponds to the '/' page (main_page) as I changed the code in '/test' to begin to get a trial and error sense of how it works it made no change, now I realize, I can comment out the entire add and commit process yet it still will add the information into the database and redirect the url to 'confirm' instead of 'test' Clearly the '/test' page is running the code from the main_page but why would this be? The only code I have not provided is connecting to MySQL which was the same method as in Beginners Guide. and the html which is the same as in the guide on both pages. Both tables are setup and have data from the SQL console.


class Comment(db.Model):

__tablename__ = "comments"

id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(4096))

class User(db.Model):

__tablename__ = "users"

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80))

@app.route("/test", methods=["GET", "POST"])

def test():

if request.method == "GET":
      return render_template("test.html", users=User.query.all())

#user = User(username=request.form["contents"])
#User.session.add(user)
#User.session.commit()
return redirect(url_for('test'))

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

def index():

if request.method == "GET":
      return render_template("main_page.html", comments=Comment.query.all())

comment = Comment(content=request.form["contents"])
db.session.add(comment)
db.session.commit()
return redirect(url_for('confirm'))

Did you reload your webapp after commenting out the database stuff in /test?

Yes it is reloaded.

I don't see any way that that could be happening. Try putting some logging in to see what functions are being called. If you print to sys.stderr, it will appear in your server log.

I attempted to make the sys.stderr comments but it did not work the way I intended it and decided to prove the issue in another way. So here is all my code sorry about formatting. Both '/' and '/test' have a text box, both text boxes work and add data into a table "comments" in the database michalr$comments. However '/test' is only redirecting the page, and at that it is doing so incorrectly!

It seems that the GET part of the function is used correctly I get the test.html, but when it comes to POST for what ever reason it will always use the '/' response. Text box entry from either page goes to the '/cars' page that is only called in the '/' page. If you like to use the page and see first hand,

michalr.pythonanywhere

user :michalr

pass: Ryan2016

I am really unsure what to do at this point, any help would be greatly appreciated.


from flask import Flask, redirect, render_template, request, url_for

from flask.ext.sqlalchemy import SQLAlchemy


app = Flask(__name__)  #activate flask

app.config["DEBUG"] = True #debug

##connect to SQL database
SQLALCHEMY_DATABASE_URI = "mysql+mysqlconnector://{username}:{password}@{hostname}/{databasename}".format(

    username="michalr",
    password="Ryan2016",
    hostname="michalr.mysql.pythonanywhere-services.com",
    databasename="michalr$comments",

)

app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
app.config["SQLALCHEMY_POOL_RECYCLE"] = 299
db = SQLAlchemy(app)

###################### MAKE TABLE
class Comment(db.Model):

    __tablename__ = "comments"
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(4096))

##################### MAKE TEST TABLE
class User(db.Model):

    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80))

######################## TEST
@app.route("/test", methods=["GET", "POST"])

def test():

    if request.method == "GET":
            return render_template("test.html", users=User.query.all())
    return redirect(url_for('index'))
    #POST IS NOT COMMITING OR ADDING ANYTHING

################### MAIN PAGE
@app.route("/", methods=["GET", "POST"])

def index():

    if request.method == "GET":
            return render_template("main_page.html", comments=Comment.query.all())

    comment = Comment(content=request.form["contents"])
    db.session.add(comment)
    db.session.commit()
    return redirect(url_for('cars'))

####################### CARS
@app.route("/cars")

def cars():

    return render_template("car.html")

[edited by admin: formatting]

umm- you should probably change your passwords

also- if your #POST IS NOT COMMITING OR ADDING ANYTHING is where you are having trouble, then yes- post would not add anything. That's because the redirect just tells the browser to redirect to that page. (it just becomes a plain get)

Sorry so what I mean at the "#POST IS NOT COMMITTING OR ADDING is that it SHOULD only redirect however it DOES go through the process of committing to the database. Its as if when ever it gets a POST request it goes into

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

Then executes the appropriate POST procedure.

Sorry, I'm finding it a bit hard to work out what the issue is. What is the /test view adding to the database? What is it that's getting committed?

Is it possible that you're just not reloading the website after making changes, so it's running old code?

So data should be taken in from a text area, it is submitted and stored into a database. Both pages have a text area and submit button. Both pages submit data into the database. The '/test' page should not add the data.

I am refreshing the page I can change things and it will react, so long the change is not made in else statement of test().

Template changes are picked up without a reload, but if you change the Python code, you need to reload the web app from the "Web" tab.

Yes, the page is reloaded and running the code posted above.

OK. And, just to make sure I really understand you, you're saying that when you hit the /test/ URL, you get behaviour that is consistent with it running the code for the / URL?

Kind of. When you go to /test/ you get the correct page (the html is different than '/' ) however the text area acts as the / URL which it should not.

so if request.method="GET" each page works correctly.

If request.method = "POST" both will always do what the / URL reads. NEVER what the /test/ says.

I think the problem is that you're using action="." in your forms.

  • For the URL http://michalr.pythonanywhere.com/, "." means http://michalr.pythonanywhere.com/
  • For the URL http://michalr.pythonanywhere.com/test, "." also means http://michalr.pythonanywhere.com/
  • For the URL http://michalr.pythonanywhere.com/test/, "." means http://michalr.pythonanywhere.com/test/

Note the trailing slash in the last case.

Yep that made the difference. Thank you for the help and patience!

Excellent, thanks for confirming!