So the whole thing basically works – i can Register a new user, i can login i can get the shares quotes etc.
But as soon as i try to buy a share, i get an error: ValueError: NOT NULL constraint failed: portfolio.shares.
CODE:
@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
"""Buy shares of stock"""
# if request method is GET, display buy.html form
if request.method == "GET":
return render_template("buy.html")
# if request method is POST
else:
# save stock symbol, number of shares, and quote dict from form
symbol = request.form.get("symbol")
shares = request.form.get("shares")
quote = lookup(symbol)
# return apology if symbol not provided or invalid
if quote == None:
return apology("must provide valid stock symbol", 400)
# return apology if shares not provided or invalid
if not shares or not shares.isdigit() or int(shares) <= 0:
return apology("must provide a positive number of shares", 400)
# cast symbol to uppercase and cast shares to int, in order to work with them
symbol = symbol.upper()
shares = int(shares)
purchase = quote['price'] * shares
# make sure user can afford current stock, checking amount of cash in users table
# select this user's cash balance from users table
balance = db.execute("SELECT cash FROM users WHERE id = :id", id=session["user_id"])
balance = balance[0]['cash']
remainder = balance - purchase
# if purchase price exceeds balance, return error
if remainder < 0:
return apology("insufficient funds", 400)
# query portfolio table for row with this userid and stock symbol:
row = db.execute("SELECT * FROM portfolio WHERE userid = :id AND symbol = :symbol",
id=session["user_id"], symbol=symbol)
# if row doesn't exist yet, create it but don't update shares
if len(row) != 1:
db.execute("INSERT INTO portfolio (userid, symbol) VALUES (:id, :symbol)",
id=session["user_id"], symbol=symbol)
# get previous number of shares owned
oldshares = db.execute("SELECT shares FROM portfolio WHERE userid = :id AND symbol = :symbol",
id=session["user_id"], symbol=symbol)
oldshares = oldshares[0]["shares"]
# add purchased shares to previous share number
newshares = oldshares + shares
# update shares in portfolio table
db.execute("UPDATE portfolio SET shares = :newshares WHERE userid = :id AND symbol = :symbol",
newshares=newshares, id=session["user_id"], symbol=symbol)
# update cash balance in users table
db.execute("UPDATE users SET cash = :remainder WHERE id = :id",
remainder=remainder, id=session["user_id"])
# update history table
db.execute("INSERT INTO history (userid, symbol, shares, method, price) VALUES (:userid, :symbol, :shares, 'Buy', :price)",
userid=session["user_id"], symbol=symbol, shares=shares, price=quote['price'])
# redirect to index page
return redirect("/")
HTML:
{% extends "layout.html" %}
{% block title %}
Buy
{% endblock %}
{% block main %}
<form action="/buy" method="post">
<div style="width:30%; margin: auto; class="form-group">
<input class="form-control" name="symbol" placeholder="Symbol" type="text">
</div>
<div class="form-group">
<input style="width:30%; margin: auto; class="form-control" name="shares" placeholder="Shares" type="number" min="0">
</div>
<button class="btn btn-primary" type="submit">Buy</button>
</form>
{% endblock %}
.db
CREATE TABLE portfolio (
id INTEGER PRIMARY KEY AUTOINCREMENT,
userid INTEGER NOT NULL,
symbol TEXT NOT NULL,
shares INTEGER NOT NULL,
FOREIGN KEY (userid) REFERENCES users(id)
);
CREATE TABLE history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
userid INTEGER NOT NULL,
symbol TEXT NOT NULL,
shares INTEGER NOT NULL,
price REAL NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (userid) REFERENCES users(id)
);
I googled, i asked my LLM, i searched in different forums, stackoverflow, reddit, ytb etc.
Along the way i was able to fix some earlier Problems but sadly on the check50 i still get this:
**:( buy handles valid purchase
application raised an exception (see the log for more details)**
log:
sending GET request to /signin
sending POST request to /login
sending POST request to /buy
exception raised in application: ValueError: NOT NULL constraint failed: portfolio.shares
Please tell me if you need aditional information, i am thankfull for every input/help i get, i im stuck with this since over a week now 🙂
BG
3