0

I have an issue with my index function after a user newly registers. After registering, a new row is created in the table users with a cash value set to 10000 by default.

After registering, the user is redirected to index.html which searches again the users table for the cash where id=session['user_id']. However, for a newly registered user, the SQL select function returns nothing, resulting in an error when the cash is queried in index. I'm not sure why this happens and if there is some way to prevent it.

The error I get:

    ERROR:flask.app:Exception on / [GET]
        Traceback (most recent call last):
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ubuntu/workspace/pset7/finance/helpers.py", line 33, in decorated_function
    return f(*args, **kwargs)
  File "/home/ubuntu/workspace/pset7/finance/application.py", line 73, in index
    cash = cash_dict[0]['cash']
IndexError: list index out of range
INFO:werkzeug:10.240.1.220 - - [16/Dec/2018 14:52:51] "GET / HTTP/1.1" 500 -
ERROR:werkzeug:Error on request:
Traceback (most recent call last):
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/werkzeug/serving.py", line 270, in run_wsgi
    execute(self.server.app)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/werkzeug/serving.py", line 258, in execute
    application_iter = app(environ, start_response)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1748, in handle_exception
    return self.finalize_request(handler(e), from_error_handler=True)
  File "/home/ubuntu/workspace/pset7/finance/application.py", line 311, in errorhandler
    return apology(e.name, e.code)
AttributeError: 'IndexError' object has no attribute 'name'

This seems to be caused by cash = cash_dict[0]['cash'] Where cash_dict is a SQL query to get the balance from the users table and normally returns as [{'cash': 10000}]

However, I cannot figure out why my query doesnt work straight after a user registers but only works after logging out then in again. Refreshing the index page also does not work.

Index function:

# Get data about all stock that a user owns
rows = db.execute("SELECT * FROM owned WHERE user_id = :id", id=session['user_id'])
total_stock_value = 0.00

# Check if user owns shares
if not rows:

    # Set all values to N/A if no stock is held
    rows = [{'stock_symbol': 'N/A', 'stock_name': 'N/A', 'amount_of_shares': 0, 'stock_price': 0, 'stock_value': 0}]
else:
    # Iterate over all the rows that the database query pulled
    for row in rows:
        stock = lookup(row['stock_symbol'])

        # Get stock name using lookup
        row["stock_name"] = stock['name']

        # Get price of one share using lookup
        row["stock_price"] = stock['price']

        # Calculate value of the stock held
        row["stock_value"] =  float(row['amount_of_shares']) * stock['price']

        # Add the value of this stock to total stock holding value
        total_stock_value += row["stock_value"]

# Obtain amount of cash user has
cash_dict = db.execute("SELECT cash FROM users WHERE id = :id", id=session['user_id'])
print(cash_dict)
cash = cash_dict[0]['cash']
# Remove from here
print(cash)
cash2 = db.execute("SELECT cash FROM users WHERE id = :id", id=session["user_id"])
print(cash2)
# Remove upto here
# Calculate net worth of user
total_value = total_stock_value + cash
return render_template("index.html",
                        rows=rows, cash=cash, total_value=total_value,
                        total_stock_value=total_stock_value)

Register function:

"""Register user"""

# Forget any user_id
session.clear()

if request.method == "POST":

    # Ensure username was submitted
    if not request.form.get("username"):
        return apology("username required", 400)

    # Ensure password was submitted
    elif not request.form.get("password"):
        return apology("password required", 400)

    # Ensure password-confirmation provided
    elif request.form.get("confirmation") != request.form.get("password"):
        return apology("passwords must match", 400)

    # Insert username and hashed password into finance.db
    result = db.execute("INSERT INTO users (username, hash, cash) VALUES (:username, :hash, 10000)",
                        username = request.form.get("username"),
                        hash = generate_password_hash(request.form.get("password")))

    # Return error if username is duplicate
    if not result:
        return apology("Username taken", 400)

    # Remember which user has logged in
    session["user_id"] = "id"

    # Redirect user to home page
    return redirect("/")

# User reached route via GET method (by clicking register)
else:
    return render_template("register.html")

1 Answer 1

1

There's a problem here session["user_id"] = "id". "id" is a string literal, not users.id from the database.

Remember this Hint from the spec:

If str is an INSERT, and the table into which data was inserted contains an autoincrementing PRIMARY KEY, then execute returns the value of the newly inserted row’s primary key.

NB: The "AUTOINCREMENT" does not need to be set in the database on user.id, as long id is integer and primary key. See this info from sqlite3 doc.

1
  • Thanks that solved it. It seems so obvious, but in all my testing I was using a logged in user, not a newly registered one so this problem didnt crop up until check50. Dec 17, 2018 at 9:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .