2017-04-10 61 views
0

慢慢構建我的應用程序(對於CS50),它似乎可以正常工作,但只能寫入數據庫一次。我可以前往網站,下訂單,並且每次都會在HTML頁面上成功顯示我的訂單。但只有一次它會將訂單寫入數據庫並顯示它。我可以註銷,但仍然只有一個訂單將被寫入數據庫。Python/MySQL:成功寫入數據庫只有一次

所有的
@app.route("/buy", methods=["GET", "POST"]) 
@login_required 
def buy(): 
    if request.method == "POST": 
     #http://stackoverflow.com/questions/32640090/python-flask-keeping-track-of-user-sessions-how-to-get-session-cookie-id 
     id = session.get('user_id') 

     url_start = 'http://download.finance.yahoo.com/d/quotes.csv?s=' 
     url_middle = request.form["symbol"] 
     url_end = '&f=nsl1d1t1c1ohgv&e=.csv' 
     full_url = url_start + url_middle + url_end 

     # http://stackoverflow.com/questions/21351882/reading-data-from-a-csv-file-online-in-python-3 
     response = urllib.request.urlopen(full_url) 

     datareader = csv.reader(io.TextIOWrapper(response)) 
     quote_list = list(datareader) 

     num_shares = request.form["num_shares"] 

     name = quote_list[0][0] 
     symbol = quote_list[0][1] 
     price = float(quote_list[0][2]) 

     #http://stackoverflow.com/questions/12078571/jinja-templates-format-a-float-as-comma-separated-currency 
     total_cost = round((float(price) * 100.0) * float(num_shares)/100.0,2) 

     username = db.execute("SELECT username FROM users WHERE id = :id", id=id) 
     username = username[0] 
     username = username.get('username') 

     db.execute("INSERT INTO purchases (id, symbol, name, shares, price, total) VALUES(:id, :symbol, :name, :shares, :price, :total)", 
      id=id, symbol=symbol, name=name, price=price, shares=num_shares, total=total_cost) 

     return render_template("bought.html", username=username, id=id, name=name, symbol=symbol, price=price, num_shares=num_shares, total_cost=total_cost) 
    else: 
     return render_template("buy.html") 

回答

1

首先,大多數的所有問題都可以通過分離功能於零件和檢查,如果每個部分按預期工作來解決,所以讓我們重構代碼位。

# additional import for generating URL from parts, 
# not by concatenating strings 
import urllib.parse 


@app.route("/buy", methods=["GET", "POST"]) 
@login_required 
def buy(): 
    if request.method != "POST": 
     return render_template("buy.html") 

    # http://stackoverflow.com/questions/32640090/python-flask-keeping-track-of-user-sessions-how-to-get-session-cookie-id 
    user_id = session.get('user_id') 

    # what is "full_url"? 
    # to which resource and what we get with it? 
    full_url = generate_url(symbol=request.form["symbol"]) 

    # http://stackoverflow.com/questions/21351882/reading-data-from-a-csv-file-online-in-python-3 
    response = urllib.request.urlopen(full_url) 

    datareader = csv.reader(io.TextIOWrapper(response)) 
    quote_list = list(datareader) 

    num_shares = request.form["num_shares"] 

    # what first element means, 
    # if it contains info about specific data 
    # there should be name for it 
    quote_list_first_element = quote_list[0] 
    name = quote_list_first_element[0] 
    # is this symbol different from one in "request.form"? 
    symbol = quote_list_first_element[1] 
    price = float(quote_list_first_element[2]) 

    # http://stackoverflow.com/questions/12078571/jinja-templates-format-a-float-as-comma-separated-currency 
    total_cost = get_total_cost(price, num_shares) 

    username = fetch_user_name(user_id) 

    save_purchase(user_id=user_id, 
        symbol=symbol, 
        name=name, 
        price=price, 
        num_shares=num_shares, 
        total_cost=total_cost) 

    return render_template("bought.html", 
          username=username, 
          id=user_id, 
          name=name, 
          symbol=symbol, 
          price=price, 
          num_shares=num_shares, 
          total_cost=total_cost) 


def fetch_user_name(user_id): 
    username = db.execute("SELECT username FROM users WHERE id = :user_id", 
          user_id=user_id) 
    username = username[0] 
    username = username.get('username') 
    return username 


def save_purchase(user_id, name, num_shares, 
        price, symbol, total_cost): 
    db.execute(
     "INSERT INTO purchases (id, symbol, name, num_shares, price, total) " 
     "VALUES (:user_id, :symbol, :name, :num_shares, :price, :total)", 
     # FIXME: if "purchases" table's "id" column is a primary key 
     # here we are saving purchase by user id 
     # not by purchase id (which probably is auto-incremented 
     # and should not be specified in insert query at all), 
     # so for each user we will have only one purchase since primary key is unique 
     user_id=user_id, 
     symbol=symbol, 
     name=name, 
     price=price, 
     # maybe it will be better to rename column into "num_shares"? 
     shares=num_shares, 
     # maybe it will be better to rename column into "total_cost"? 
     total=total_cost) 


def get_total_cost(price, num_shares): 
    return round((float(price) * 100.0) * float(num_shares)/100.0, 2) 


def generate_url(symbol): 
    scheme = 'http' 
    netloc = 'download.finance.yahoo.com' 
    path = '/d/quotes.csv' 
    params = '' 
    # what 's' query parameter means? 
    # looks like it stands for "symbol", but which one? 
    # is it product label or something else? 
    query_dict = dict(s=symbol, 
         f='nsl1d1t1c1ohgv', 
         e='.csv') 
    query_str = urllib.parse.urlencode(query_dict) 
    fragment = '' 
    components = [scheme, netloc, path, params, query_str, fragment] 
    return urllib.parse.urlunparse(components) 

現在我們可以看到,我們保存每個購買的用戶ID,但它可能自動遞增的列或有用戶ID列,而不是購買的ID,我不知道你的數據庫架構是什麼

如果purchases表的id列自動遞增,我們可以刪除user_id參數

def save_purchase(name, num_shares, 
        price, symbol, total_cost): 
    db.execute(
     "INSERT INTO purchases (symbol, name, num_shares, price, total) " 
     "VALUES (:symbol, :name, :num_shares, :price, :total)", 
     symbol=symbol, 
     name=name, 
     price=price, 
     shares=num_shares, 
     total=total_cost) 

如果purchases表有兩個iduser_id colu MNS我們要插入記錄與user_id規定應該像

def save_purchase(user_id, name, num_shares, 
        price, symbol, total_cost): 
    db.execute(
     "INSERT INTO purchases (user_id, symbol, name, num_shares, price, total) " 
     "VALUES (:user_id, :symbol, :name, :num_shares, :price, :total)", 
     user_id=user_id, 
     symbol=symbol, 
     name=name, 
     price=price, 
     shares=num_shares, 
     total=total_cost) 

希望它能幫助。

+0

謝謝,你的建議很好,但我的答案實際上要簡單得多。 –

+0

如果你的答案在我的假設中完全一樣,那麼你的答案會更簡單:你試圖用相同的主鍵值保存記錄 –

+0

嗯,我的意思是說,把它分解成函數是一個很好的建議,但核心問題只是它被設置爲獨一無二的。 –

0

簡單的答案:我已將購買表設置爲與用戶表相同,id_num在兩個表中都是唯一的。它應該在用戶表中是唯一的,因爲用戶是唯一的。但它在購買表中不應該是唯一的,因爲同一個用戶可以進行多次購買。